home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Visual Database / Visual Foxpro 6.0 (Ent. Edition) / Vf6ent Extractor.EXE / TOOLS / CONVERT / CONVERT.PRG < prev    next >
Encoding:
Text File  |  1998-05-26  |  266.6 KB  |  9,031 lines

  1. *- See C_CONVERSION_LOC in CONVERT.H for current version #
  2.  
  3. *- Visual FoxPro 3.0 Converter Utility
  4. *- (c) Microsoft Corporation 1995,1996,1998
  5. *-
  6. *-
  7. *- Developer Note:
  8. *-
  9. *- The following hidden properties are used in converted forms:
  10. *-
  11. *- 1)  ReleaseErase
  12. *- 
  13. *-     This is used by controls to indicate that when they are
  14. *- released, their image should remain on the form. Read uses this
  15. *- because when you do after a READ terminates, the images of the
  16. *- objects remain on the form.
  17. *- 
  18. *- 2)  ReleaseWindows
  19. *- 
  20. *-     This is used by converted forms to support the Release
  21. *- Windows checkbox in the generate or project manager dialog.
  22. *- 
  23. *- 3)  ErasePage
  24. *- 
  25. *-     Nested READs within a form are accomplished using "invisible"
  26. *- form pages.  When READ switches form pages, he doesn't want to erase
  27. *- the objects at the prior read level, so he makes the ErasePage
  28. *- property be false.
  29. *- 
  30. *- 
  31. *- Changes: Support for Macintosh (10/16/95 jd)
  32. *-          Support for Visual Foxpro 5.0 (05/16/96 jd)
  33. *-
  34.  
  35. #INCLUDE "convert.h"
  36.  
  37. PARAMETER pFilename,pFiletype,pVersion,pProgCall
  38.  
  39. *- pFileName:    fully qualified name of file to convert (C)
  40. *- pFileType:    type of file (C)
  41. *- pVersion:    version of file (C)
  42. *- pProgCall:    new param -- if .T., is being called from within another app (jd 07/25/96)
  43.  
  44. LOCAL i
  45.  
  46. PRIVATE gTransport            && which transporter to use
  47. PRIVATE gReturnVal            && name of file to return to VFP
  48. PRIVATE gLog                && accumulate log file info
  49. PRIVATE gError                && global error flag
  50. PRIVATE gAShowMe            && display transporter dialog?
  51. PRIVATE gOPJX                && PJX object
  52. PRIVATE gOMaster            && Master object
  53. PRIVATE gOTherm                && thermometer object
  54. PRIVATE giCallingProg        && index into PROGRAM()
  55.  
  56. gTransport = ""
  57. gReturnVal = -1
  58. gLog = ""
  59. gError = .F.
  60.  
  61. *- hold responses to transporter dialog
  62. DIMENSION gAShowMe[N_MAXTRANFILETYPES,9]
  63. FOR i = 1 TO N_MAXTRANFILETYPES
  64.     gAShowMe[i,1] = .T.        && show the dialog?
  65.     gAShowMe[i,2] = 1        && choice
  66.     gAShowMe[i,3] = ""        && font name
  67.     gAShowMe[i,4] = 0        && font size
  68.     gAShowMe[i,5] = ""        && font style
  69.     gAShowMe[i,6] = ""        && from platform
  70.     gAShowMe[i,7] = .T.        && convert new objects
  71.     gAShowMe[i,8] = .T.        && convert more recently modified objects
  72.     gAShowMe[i,9] = .T.        && replace all objects
  73. NEXT
  74.  
  75. gOPJX = .NULL.
  76. gOTherm = .NULL.
  77. giCallingProg = 0
  78.  
  79. DO CASE
  80.     CASE PARAMETERS() = 0
  81.         *- new feature for selectively converting 3.0 SCX and VCX files
  82.         m.pFileType = C_SCREENTYPEPARM
  83.         m.pFileName = ""
  84.         m.pVersion = C_30VERS
  85.     CASE PARAMETERS() == 3 AND PROGRAM(0) = "CONVERT"
  86.         *- okay -- classic mode of calling convert.app
  87.     CASE TYPE("pProgCall") == 'L' AND pProgCall
  88.         *- is being called from another program -- need to trap index into PROGRAM()
  89.         LOCAL i
  90.         FOR i = 1 TO 128
  91.             IF PROGRAM() == PROGRAM(i)
  92.                 giCallingProg = MAX(1,i - 1)
  93.                 EXIT
  94.             ENDIF
  95.         NEXT
  96.         *- note: if this fails (i.e., can;t locate current program in the PROGRAM()
  97.         *- array, giCallingProg will remain at 0 (MASTER)
  98.     OTHERWISE
  99.         *- called with wrong parameters
  100.         =MESSAGEBOX(E_BADCALL_LOC)
  101.         RETURN gReturnVal
  102. ENDCASE
  103.  
  104. IF VERSION(4) < C_LATESTVER
  105.     =MESSAGEBOX(E_BADFOX1_LOC + C_LATESTVER + E_BADFOX2_LOC)
  106.     RETURN gReturnVal
  107. ENDIF
  108.  
  109. IF EMPTY(_transport)
  110.     *- if not specified, use the built-in one
  111.     gTransport = "transprt"
  112. ELSE
  113.     IF FILE(_transport)
  114.         gTransport = _transport
  115.     ELSE
  116.         =MESSAGEBOX(E_NOTRANS_LOC)
  117.         RETURN
  118.     ENDIF
  119. ENDIF
  120.  
  121. gOMaster = CREATE("MasterConvert",m.pFilename,m.pFiletype,m.pVersion)
  122. IF TYPE("gOMaster") # "O"
  123.     *- error creating object, so fail
  124.     =MESSAGEBOX(E_NOSTART_LOC)
  125.     RETURN gReturnVal
  126. ENDIF
  127.  
  128. IF gOMaster.lHadError
  129.     *- problem with parms, or some other kind of initialization problem
  130.     =MESSAGEBOX(E_NOSTART_LOC)
  131. ELSE
  132.     gOMaster.DoConvert
  133. ENDIF
  134.  
  135. gOPJX = .NULL.
  136. gOTherm = .NULL.
  137. gOMaster = .NULL.
  138.  
  139. RELEASE gOTherm, gOPJX, gOMaster
  140.  
  141. IF gError
  142.     *- some kind of fatal error occurred, so clean up as best we can
  143.     *- CLEAR ALL
  144.     RETURN -1
  145. ENDIF
  146.  
  147. RETURN gReturnVal
  148.  
  149. *------------------------------------------------*
  150.  
  151.  
  152. **************************************************
  153. ******************* Classes **********************
  154. **************************************************
  155.  
  156. *************************************
  157. DEFINE CLASS Cvt AS custom
  158. *************************************
  159.     *- this class is a base class for all other classes
  160.     *- and provides for certain properties and methods they have in common
  161.  
  162.     lHadError = .F.
  163.     lLog = .F.                && log file?
  164.     cLogFile = ""            && the file to write the log to
  165.     lDevMode = .F.            && dev mode?
  166.     cCodeFile = ""            && cCodeFile
  167.     lLocalErr = .F.            &&
  168.     lHadLocErr = .F.
  169.     lShown1994 = .F.
  170.     cCurrentFile = ""        && the file currently being processed
  171.     dtStartTime = DATETIME(1995,1,1)
  172.     dtEndTime = DATETIME(1995,1,1)
  173.  
  174.     *------------------------------------
  175.     PROCEDURE Error                && Cvt
  176.     *------------------------------------
  177.         PARAMETER errorNum, method, line
  178.  
  179.         LOCAL iCtr, iFH, cErrMsg
  180.  
  181.         IF errorNum = 39    &&benign error sometimes caused by Gather
  182.             RETURN
  183.         ENDIF
  184.         
  185.         IF THIS.lLocalErr
  186.             *- enable testing for certain conditions without 
  187.             *- bringing down the house
  188.             THIS.lHadLocErr = .T.
  189.             RETURN
  190.         ENDIF
  191.             
  192.         *- turn off Escape
  193.         ON ESCAPE
  194.         SET ESCAPE OFF
  195.  
  196.         IF errorNum = 0
  197.             *- user pressed <escape>, and wants to cancel
  198.             cErrMsg = C_ESCLOGMSG_LOC
  199.         ELSE
  200.             ON ERROR m.err = .T.        && keep from returning here
  201.             cErrMsg = E_FATAL1_LOC + C_CRLF + ;
  202.                     E_ERR1_LOC + message() + C_CRLF + ;
  203.                     E_ERR2_LOC + ALLT(STR(m.Errornum)) + C_CRLF + ;
  204.                     E_ERR3_LOC + m.Method + C_CRLF + ;
  205.                     E_ERR5_LOC + message(1)+ C_CRLF + ;
  206.                     E_ERR6_LOC + IIF(EMPTY(THIS.cCurrentFile),E_ERR7_LOC,THIS.cCurrentFile)
  207.  
  208.         ENDIF
  209.  
  210.         THIS.lHadError = .T.
  211.  
  212.         *- force write an error to a logfile
  213.         IF EMPTY(THIS.cLogFile) AND errorNum # 0
  214.             *- not logging, so make up a name
  215.             THIS.cLogFile = SET("DEFA") + CURDIR() + C_ERRLOG_LOC + '.' + C_LOGEXT
  216.             iCtr = 1
  217.             DO WHILE FILE(THIS.cLogFile) AND m.iCtr < 99
  218.                 THIS.cLogFile = SET("DEFA") + CURDIR() + LEFT(C_ERRLOG_LOC,6) + RIGHT(STR(iCtr + 100),2) + '.' + C_LOGEXT
  219.                 m.iCtr = m.iCtr + 1
  220.             ENDDO
  221.         ENDIF
  222.  
  223.         *- open logfile
  224.         IF !EMPTY(THIS.cLogFile)
  225.             IF m.errornum == I_DISKFULLERR
  226.                 *- disk is full, so use MESSAGEBOX
  227.                 =MESSAGEBOX(E_DISKFULL_LOC)
  228.             ELSE
  229.                 iFH = FCREATE(THIS.cLogFile)
  230.                 IF iFH >= 0
  231.                     *- opened file okay
  232.                     *- add error info
  233.                     IF TYPE("glog") # 'C'
  234.                         *- something happened -- maybe the Transporter killed it
  235.                         gLog = ""
  236.                     ENDIF
  237.                     m.gLog = m.gLog + C_CRLF + m.cErrMsg + C_CRLF
  238.                     =FWRITE(iFH,m.gLog)
  239.                     =FCLOSE(iFH)
  240.                 ENDIF
  241.             ENDIF        && disk is full
  242.         ENDIF
  243.  
  244.         IF L_DEBUG AND L_DEBUGSUSPEND
  245.             ACTI WIND DEBUG
  246.             SUSPEND
  247.         ENDIF
  248.  
  249.         *- attempt to extricate from this mess
  250.         *- maybe the erring object was an object on a screen
  251.         DO CASE
  252.             CASE TYPE("THIS.formRef") = 'O'
  253.                 *- true if SCX Object
  254.                 THIS.formRef.Cleanup
  255.                 IF THIS.formRef.projCall
  256.                     *- the erring object was part of a project
  257.                     gOPJX.Cleanup
  258.                 ENDIF
  259.             CASE TYPE("THIS.projcall") = "L"
  260.                 *- true if a screen or report
  261.                 IF THIS.projCall
  262.                     gOPJX.Cleanup
  263.                 ELSE
  264.                     THIS.Cleanup
  265.                 ENDIF
  266.             OTHERWISE
  267.             *CASE TYPE("THIS.pjx25alias") = "C"
  268.                 *- true if a project
  269.                 THIS.Cleanup
  270.         ENDCASE
  271.         IF ErrorNum # 0
  272.             gOTherm = .NULL.
  273.             IF m.errornum # I_DISKFULLERR
  274.                 IF MESSAGEBOX(E_FATAL_LOC + E_FATAL2_LOC + SYS(2027,THIS.cLogFile) + E_FATAL3_LOC,MB_YESNO) = IDYES
  275.                     MODIFY FILE (THIS.cLogFile)
  276.                 ENDIF
  277.             ENDIF
  278.         ENDIF
  279.         gError = .T.
  280.         IF giCallingProg > 1
  281.             *- special case, if converter was called from within a program (jd 07/25/96)
  282.             LOCAL cCallingProg
  283.             cCallingProg = PROGRAM(giCallingProg)
  284.             RETURN TO &cCallingProg
  285.         ELSE
  286.             RETURN TO MASTER
  287.         ENDIF
  288.     
  289.     ENDPROC        &&  Error
  290.  
  291.     *------------------------------------
  292.     PROCEDURE WriteLog            && Cvt
  293.     *------------------------------------
  294.         PARAMETER cFileName,cAction
  295.  
  296.         *- changed to always accumulate log -- THIS.llog isn't always available! (jd 02/13/96)
  297.         m.gLog = m.gLog + UPPER(cFileName) + IIF(EMPTY(cAction),"",": " + cAction) + C_CRLF
  298.  
  299.     ENDPROC
  300.  
  301.     *------------------------------------
  302.     PROCEDURE BeginLog            && Cvt
  303.     *------------------------------------
  304.         PARAMETER cFileName
  305.  
  306.         THIS.dtStartTime = DATETIME()
  307.         THIS.WriteLog(m.cFileName,C_BEGIN_LOC + " " + TTOC(DATETIME()))
  308.  
  309.     ENDPROC
  310.  
  311.     *------------------------------------
  312.     PROCEDURE EndLog            && Cvt
  313.     *------------------------------------
  314.         PARAMETER cFileName
  315.  
  316.         THIS.dtEndTime = DATETIME()
  317.         THIS.WriteLog(SYS(2027,m.cFileName),C_END_LOC + ": " + TTOC(DATETIME()) + " " + ;
  318.             IIF(THIS.dtStartTime # DATETIME(1995,1,1),"(" + C_SUCCESSCONV_LOC + LTRIM(STR(THIS.dtEndTime - THIS.dtStartTime)) + ;
  319.             C_SECONDS_LOC + ")",""))
  320.  
  321.     ENDPROC
  322.  
  323.  
  324.     *------------------------------------
  325.     PROCEDURE IsDBF                && Cvt
  326.     *------------------------------------
  327.     *- Check to see if the file can be opened as a DBF
  328.  
  329.         PARAMETER cFile
  330.  
  331.         LOCAL m.lDBF, m.savearea
  332.  
  333.         m.lDBF = .T.
  334.  
  335.         m.savearea = SELECT()
  336.         SELECT 0
  337.  
  338.         THIS.lLocalErr = .T.
  339.         USE (m.cFile) 
  340.         THIS.lLocalErr = .F.
  341.  
  342.         IF THIS.lHadLocErr
  343.             m.lDBF = .F.
  344.             THIS.lHadLocErr = .F.
  345.         ENDIF
  346.         USE
  347.  
  348.         SELECT (m.savearea)
  349.  
  350.         RETURN m.lDBF
  351.  
  352.     ENDPROC
  353.  
  354.     *------------------------------------
  355.     PROCEDURE GetPlatformCount
  356.     *------------------------------------
  357.         *- Get a list of the platforms in this file.
  358.         *- return in passed array
  359.  
  360.         PARAMETER cSCXFile, aPlatforms
  361.  
  362.         IF !FILE(cSCXFile) OR !Readable(m.cSCXFile) OR !THIS.IsDBF(cSCXFile)
  363.             *- We have a problem. Return and it will be sorted out later
  364.             RETURN
  365.         ENDIF
  366.  
  367.         USE (cSCXFile) ALIAS _temppct IN 0
  368.         SELECT DISTINCT platform ;
  369.             FROM _temppct ;
  370.             WHERE !DELETED() ;
  371.             INTO ARRAY aPlatforms
  372.  
  373.         USE IN _temppct
  374.  
  375.     ENDPROC
  376.  
  377.     *------------------------------------
  378.     FUNCTION GetPlatform        && ConverterBase
  379.     *------------------------------------
  380.         PARAMETER iPlatform
  381.         *- need to deal with creating files for other platforms than the current one
  382.         iPlatform = IIF(PARAMETERS() = 0, 1, iPlatform)
  383.         IF iPlatform = 1
  384.             DO CASE
  385.                 CASE _windows
  386.                     RETURN C_WINDOWS
  387.                 CASE _mac
  388.                     RETURN C_MAC
  389.                 CASE _dos
  390.                     RETURN C_DOS
  391.                 CASE _unix    
  392.                     RETURN C_UNIX
  393.             ENDCASE
  394.         ELSE
  395.             DO CASE
  396.                 CASE _windows
  397.                     RETURN C_MAC
  398.                 CASE _mac
  399.                     RETURN C_WINDOWS
  400.             ENDCASE
  401.         ENDIF
  402.     ENDFUNC
  403.  
  404.     *------------------------------------
  405.     PROCEDURE Cleanup            && Cvt
  406.     *------------------------------------
  407.         *- this proc is called by Error, and tries to put things back the way they were
  408.         *- this should be overridden, and given something to do
  409.     ENDPROC
  410.  
  411. ENDDEFINE
  412.  
  413. *************************************
  414. DEFINE CLASS MasterConvert AS Cvt
  415. *************************************
  416.     
  417.     *- Classes which can be replaced with others if
  418.     *- MasterConvert is sub-classed
  419.     scxConverterClass = "SCXSingleScreenConverter"
  420.     scx30ConverterClass = "SCX30Converter"
  421.     pjxConverterClass = "PJXConverter"
  422.     mnxConverterClass = ""
  423.     frxConverterClass = "FRXConverter"
  424.     fpcConverterClass = "FPCConverter"
  425.     db4ScrConverterClass = "DB4ScrConverter"
  426.     db4FrmConverterClass = "DB4FrmConverter"
  427.     db4LblConverterClass = "DB4LblConverter"
  428.     db4CatConverterClass = "DB4CatConverter"
  429.     db4QbeConverterClass = "DB4QbeConverter"
  430.     fmtConverterClass = "FmtConverter"
  431.     
  432.     *- Environment vars to save/restore
  433.     PROTECTED oldtalk, oldsafe, oldnotify, oldMess, oldmemowid,;
  434.         oldClass, oldProc, oldData, oldCompat, oldCollate, oldBlock,;
  435.         oldTrBe, oldFullPath, oldUDFParm, oldOnEscape, oldDevo, oldDebug,;
  436.         oldError, oldExact, oldDefault, oldKeyComp, oldCPDialog,;
  437.         oldPoint, oldSep, oldPath, oldLibr
  438.  
  439.     *- the SET() function here stores the default values, not the current settings!
  440.     oldtalk     = SET("TALK")
  441.     oldsafe     = SET("SAFETY")
  442.     oldescape   = SET("ESCAPE")
  443.     oldOnEscape    = ON("ESCAPE")
  444.     oldnotify   = SET("NOTIFY")
  445.     oldmess     = SET("MESSAGE",1)
  446.     oldmemowid  = SET("MEMOWIDTH")
  447.     oldClass    = SET("CLASS")
  448.     oldDefault    = SET("DEFA") + CURDIR()
  449.     oldProc     = SET("PROC")
  450.     oldData     = DBC()                        && remember full path to database (jd 04/15/96)
  451.     oldCompat   = SET("COMPATIBLE")
  452.     oldExclus   = SET("EXCLUSIVE")
  453.     oldCollate  = SET("COLLATE")
  454.     oldBlock    = SET("BLOCK")
  455.     oldTrBe     = SET("TRBE")
  456.     oldFullPath = SET("FULLPATH")
  457.     oldUDFParm  = SET("UDFP")
  458.     oldDevo        = SET("DEVE")
  459.     oldDebug    = SET("DEBUG")
  460.     oldError    = ON("ERROR")
  461.     oldExact    = SET("EXACT")
  462.     oldKeyComp    = SET("KEYCOMP")
  463.     oldCPDialog    = SET("CPDIALOG")
  464.     oldPoint    = SET("POINT")
  465.     oldSep        = SET("SEPARATOR")
  466.     oldPath        = SET("PATH")
  467.     oldLibr        = SET("LIBRARY")            && remember libraries -- may conflict with converter PROCs (jd 06/20/96)
  468.  
  469.     nCurrentWorkarea = 0
  470.     nNewWorkarea = 0
  471.     lUserCall = .T.                && converter was called by program vs. _CONVERTER
  472.  
  473.     cBackDir = ""                && backup directory for project conversions
  474.  
  475.     lHandled = .F.                && has it been dealt with?
  476.  
  477.     *- PARAMETERS and other settings
  478.     DIMENSION aConvParms[13]
  479.     aConvParms[ 1] = ""            && FP25 file name
  480.     aConvParms[ 2] = ""            && file type
  481.     aConvParms[ 3] = ""            && file version
  482.     aConvParms[ 4] = ""            && FP30 file name
  483.     aConvParms[ 5] = .T.        && platform only
  484.     aConvParms[ 6] = .F.        && special effect
  485.     aConvParms[ 7] = .F.        && developer mode
  486.     aConvParms[ 8] = ""            && code file if dev mode
  487.     aConvParms[ 9] = .F.        && create log file?
  488.     aConvParms[10] = ""            && logfile name
  489.     aConvParms[11] = .T.        && make backup
  490.     aConvParms[12] = 1            && only convert records for current platform
  491.     aConvParms[13] = 1            && which platform?
  492.  
  493.     *----------------------------------
  494.     PROCEDURE Init        && MasterConvert
  495.     *----------------------------------
  496.         PARAMETER pFilename, pFiletype, pVersion
  497.     
  498.         *- Check for program intercepted via FoxPro _CONVERTER
  499.         *- Note:  If you are subclassing converter, make sure 
  500.         *- to properly handle parameter.
  501.         *- Converter now supports no params, so only check for file if something was passed
  502.         IF PARAMETERS() = 3 AND TYPE('m.pFilename') = "C" ;
  503.           AND IIF(EMPTY(m.pFilename),.T.,FILE(m.pFilename)) AND ;
  504.           TYPE('m.pFiletype') = "C"
  505.             THIS.lUserCall = .F.
  506.             THIS.aConvParms[2] = m.pFiletype
  507.             THIS.aConvParms[3] = m.pVersion
  508.             THIS.aConvParms[4] = IIF(EMPTY(m.pFilename),"",SYS(2027,m.pFilename))            && use platform specific name
  509.         ELSE
  510.             *- incorrect set of parms passed
  511.             THIS.lHadError = .T.
  512.             RETURN
  513.         ENDIF
  514.  
  515.         THIS.nCurrentWorkarea = SELECT()
  516.         THIS.lUserCall = .T.                && converter was called by program vs. _CONVERTER
  517.  
  518.         *- values were set above
  519.                 
  520.         SET TALK OFF
  521.         SET SAFETY OFF
  522.         SET NOTIFY OFF
  523.         SET LIBRARY TO                        && close libraries -- may conflict with converter PROCs (jd 06/20/96)
  524.         
  525.  
  526.         IF L_SHOWVERSION
  527.             SET MESSAGE TO C_CONVERSION_LOC + IIF(L_DEBUG," -- DEBUGGING ON","")
  528.         ELSE
  529.             SET MESSAGE TO " "
  530.         ENDIF
  531.  
  532.         SET ESCAPE OFF
  533.  
  534.         SET PROCEDURE TO "foreign" ADDITIVE        && This has the subclasses for converting non-FoxPro files
  535.         SET PROCEDURE TO "conprocs" ADDITIVE
  536.  
  537.         SET MEMOWIDTH TO 256
  538.         SET COMPATIBLE OFF
  539.         SET EXCLUSIVE ON
  540.         SET COLLATE TO "MACHINE"
  541.         SET BLOCK TO N_BLOCKSZ
  542.         SET TRBETWEEN OFF
  543.         SET FULLPATH ON
  544.         SET UDFPARMS TO VALUE
  545.  
  546.         IF !L_DEBUG
  547.             SET DEVELOPMENT OFF
  548.             SET DEBUG OFF
  549.         ELSE
  550.             SET DEVELOPMENT ON
  551.             SET DEBUG ON
  552.         ENDIF
  553.  
  554.         SET EXACT OFF
  555.  
  556.         *- set KEYCOMP to appropriate platform
  557.         IF _mac
  558.             *SET KEYCOMP TO MAC
  559.         ELSE
  560.             SET KEYCOMP TO WINDOWS
  561.         ENDIF
  562.  
  563.         *- turn off code page conversion during conversion
  564.         SET CPDIALOG OFF
  565.  
  566.         ON ERROR
  567.  
  568.         *- for now, close data -- need to close only VFP databases when it;s working
  569.         IF !EMPTY(THIS.olddata)
  570.         *-    CLOSE DATABASE
  571.             SET DATABASE TO
  572.         ENDIF
  573.  
  574.         SET CLASS TO SprTherm ADDITIVE            && thermometer classes
  575.         SET CLASS TO CvtAlert ADDITIVE            && alert classes
  576.  
  577.         SET POINT TO '.'                        && RED00NXM -- prevent invalid values in spinners  (jd 04/15/95)
  578.         SET SEPARATOR TO ','
  579.  
  580.         SELECT 0
  581.         THIS.nNewWorkarea = SELECT()
  582.  
  583.     ENDPROC        &&  Init
  584.     
  585.     *----------------------------------
  586.     PROCEDURE Destroy
  587.     *----------------------------------
  588.         LOCAL cOld
  589.  
  590.         IF THIS.oldsafe = "ON"
  591.             SET SAFETY ON
  592.         ENDIF
  593.  
  594.         IF THIS.oldnotify = "ON"
  595.             SET NOTIFY ON
  596.         ENDIF
  597.  
  598.         IF EMPTY(THIS.oldmess)
  599.             SET MESSAGE TO
  600.         ELSE
  601.             SET MESSAGE TO THIS.oldmess
  602.         ENDIF
  603.  
  604.         IF THIS.oldtalk= "ON"
  605.             SET TALK ON
  606.         ENDIF
  607.  
  608.         SET MEMOWIDTH TO (THIS.oldmemowid)
  609.  
  610.         m.cOld = THIS.oldOnEscape
  611.         ON ESCAPE &cOld
  612.  
  613.         m.cOld = THIS.oldescape
  614.         SET ESCAPE &cOld
  615.  
  616.         m.cOld = THIS.oldCompat
  617.         SET COMPATIBLE &cOld
  618.  
  619.         m.cOld = THIS.oldExclus
  620.         SET EXCLUSIVE &cOld
  621.  
  622.         SET BLOCK TO THIS.oldBlock
  623.         SET COLLATE TO THIS.oldCollate
  624.  
  625.         m.cOld = THIS.OldClass
  626.         SET CLASS TO &cOld
  627.  
  628.         SET DEFAULT TO (THIS.oldDefault)
  629.  
  630.         IF "FOREIGN" $ SET("PROCEDURE")
  631.             RELEASE PROCEDURE foreign
  632.         ENDIF
  633.         IF "CONPROCS" $ SET("PROCEDURE")
  634.             RELEASE PROCEDURE conprocs
  635.         ENDIF
  636.  
  637.         m.cOld = THIS.oldTrbe
  638.         SET TRBETWEEN &cOld
  639.  
  640.         m.cOld = THIS.oldFullPath
  641.         SET FULLPATH &cOld
  642.  
  643.         m.cOld = THIS.oldUDFParm
  644.         SET UDFPARMS TO &cOld
  645.  
  646.         m.cOld = THIS.oldDevo
  647.         SET DEVELOPMENT &cOld    &&crashes build 4.104
  648.  
  649.         m.cOld = THIS.oldDebug
  650.         SET DEBUG &cOld
  651.  
  652.         m.cOld = THIS.oldExact
  653.         SET EXACT &cOld
  654.  
  655.         m.cOld = THIS.oldKeyComp
  656.         SET KEYCOMP TO &cOld
  657.  
  658.         m.cOld = THIS.oldCPDialog
  659.         SET CPDIALOG &cOld
  660.  
  661.         SET POINT TO (THIS.oldPoint)        && reset these values (jd 04/15/96)
  662.         SET SEPARATOR TO (THIS.oldSep)
  663.  
  664.         m.cOld = THIS.oldPath                && restore path, in case we changed it (jd 06/11/96)
  665.         SET PATH TO &cOld
  666.         
  667.         m.cOld = THIS.oldLibr                && remember libraries -- may conflict with converter PROCs (jd 06/20/96)
  668.         SET LIBRARY TO &cOld
  669.         
  670.         m.cOld = THIS.oldError
  671.         ON ERROR &cOld
  672.  
  673.         IF !EMPTY(THIS.olddata)                && restore database (jd 04/15/96)
  674.             OPEN DATABASE (THIS.olddata)
  675.         ENDIF
  676.  
  677.         SELECT (THIS.nCurrentWorkarea)
  678.  
  679.     ENDPROC        &&  Masterconvert:Destroy
  680.  
  681.  
  682.     *----------------------------------
  683.     PROCEDURE DoConvert        && masterconvert
  684.     *----------------------------------
  685.         PRIVATE g_platforms
  686.         PRIVATE aParms, oConvObject
  687.         PRIVATE g_platforms
  688.         PRIVATE cConvType
  689.         
  690.  
  691.         *- needed for GENSCRN stuff
  692.         DIMENSION g_platforms[1]
  693.         g_platforms = ""
  694.  
  695.         *- THIS.aConvParms[2] = m.pFiletype
  696.         *- THIS.aConvParms[3] = m.pVersion
  697.         *- THIS.aConvParms[4] = m.pFilename
  698.  
  699.         m.cConvType = THIS.aConvParms[2]
  700.         
  701.         DO CASE
  702.             CASE m.cConvType = C_SCREENTYPEPARM AND THIS.aConvParms[3] = C_30VERS AND ;
  703.                 EMPTY(THIS.aConvParms[4])
  704.                 *- new option (6/10/96) -- converter was called with no parameters, so show dialog
  705.                 *- for selecting SCX and VCX files, for conversion
  706.                 *- get the file or folder to update
  707.                 
  708.                 
  709.                 m.iFileDir = 1
  710.                 m.cFile = ""
  711.                 m.lSCX = .T.
  712.                 m.lVCX = .T.
  713.                 m.lRecurse = .F.
  714.                 
  715.                 *- note: we use aParms[12] to hold the lSet30Defaults value
  716.                 
  717.                 IF !THIS.GetOpts("cvtdlog30scx",C_SELECTFILE_LOC)
  718.                     RETURN
  719.                 ENDIF
  720.  
  721.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  722.  
  723.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  724.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  725.                 IF THIS.aConvParms[12] > 1
  726.                     gOTherm.Update(0)
  727.                 ENDIF
  728.                 
  729.                 *- if only doing a file, we don;t care about these values
  730.                 lSCX = IIF(iFileDir == 1,.T.,lSCX)
  731.                 lVCX = IIF(iFileDir == 1,.T.,lVCX)
  732.                 
  733.                 UpdateSCX(m.cFile, lRecurse)        && in ConProcs.PRG
  734.                 
  735.             CASE m.cConvType = C_SCREENTYPEPARM AND THIS.aConvParms[3] = C_30VERS
  736.                 *- a 3.0 SCX or VCX -- we need to re-compile, and maybe
  737.                 *- set properties that match VFP 3.0 defaults
  738.  
  739.                 *- verify user wants to convert
  740.                 IF !THIS.GetOpts("cvtalert30scx",C_CONVERT1_LOC + PARTIALFNAME(THIS.aConvParms[4],C_FILELEN) + C_CONVERT2_LOC)
  741.                     RETURN
  742.                 ENDIF
  743.  
  744.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  745.  
  746.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  747.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  748.                 IF THIS.aConvParms[12] > 1
  749.                     gOTherm.Update(0)
  750.                 ENDIF
  751.  
  752.                 =ACOPY(THIS.aConvParms,aParms)
  753.                 oConvObject = CREATE(THIS.scx30ConverterClass, @aParms, .T.)
  754.  
  755.                 IF TYPE("oConvObject") # 'O'
  756.                     *- object was not created
  757.                     THIS.lHadError = .T.
  758.                     gReturnVal = -1
  759.                     RETURN
  760.                 ENDIF
  761.  
  762.                 IF oConvObject.lHadError
  763.                     *- error creating converter object: 
  764.                     *- assume error has already been presented to user
  765.                     THIS.lHadError = .T.
  766.                     RELEASE oConvObject
  767.                     gReturnVal = -1
  768.                     RETURN
  769.                 ENDIF
  770.  
  771.                 gReturnVal = oConvObject.Converter()
  772.  
  773.                 RELEASE oConvObject
  774.  
  775.             CASE m.cConvType = C_SCREENTYPEPARM
  776.             
  777.                 *- determine number of platforms
  778.                 DIMENSION aPlatforms[1]
  779.                 aPlatforms[1] = ""
  780.                 THIS.GetPlatformCount(THIS.aConvParms[4], @aPlatforms)
  781.                 IF EMPTY(aPlatforms[1])
  782.                     *- was unable to determine platforms
  783.                     RETURN
  784.                 ENDIF
  785.                 IF ALEN(aPlatforms,1) > 1
  786.                     IF ASCAN(aPlatforms,C_WINDOWS) > 0 AND ASCAN(aPlatforms,C_MAC) > 0
  787.                         *- both platforms are there
  788.                         THIS.aConvParms[12] = 2
  789.                     ENDIF
  790.                 ENDIF
  791.  
  792.                 *- verify user wants to convert
  793.                 IF !THIS.GetOpts("cvtalertscx",C_CONVERT1_LOC + PARTIALFNAME(THIS.aConvParms[4],C_FILELEN) + C_CONVERT2_LOC)
  794.                     RETURN
  795.                 ENDIF
  796.  
  797.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  798.  
  799.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  800.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  801.                 gOTherm.Update(0)
  802.  
  803.                 *- of both platforms are present, and user wants to convert both,
  804.                 *- need to create two files
  805.                 FOR kPlat = 1 TO THIS.aConvParms[12]
  806.  
  807.                         =ACOPY(THIS.aConvParms,aParms)
  808.  
  809.                         aParms[13] = m.kPlat
  810.  
  811.                         oConvObject = CREATE(THIS.scxConverterClass, @aParms, (kPlat == 1))    && only back up first time around
  812.  
  813.                         IF TYPE("oConvObject") # 'O'
  814.                             *- object was not created
  815.                             THIS.lHadError = .T.
  816.                             gReturnVal = -1
  817.                         RETURN
  818.                     ENDIF
  819.                     
  820.                     IF oConvObject.lHadError
  821.                         *- error creating converter object: 
  822.                         *- assume error has already been presented to user
  823.                         THIS.lHadError = .T.
  824.                         RELEASE oConvObject
  825.                         gReturnVal = -1
  826.                         RETURN
  827.                     ENDIF
  828.  
  829.                     gReturnVal = oConvObject.Converter()
  830.  
  831.                     RELEASE oConvObject
  832.  
  833.                 NEXT
  834.  
  835.                 IF TYPE(gReturnVal) == "C"
  836.                     *- successful conversion
  837.                     *- if multiple platforms, return form name for the current platform
  838.                     IF THIS.aConvParms[12] > 1 AND _mac
  839.                         gReturnVal = JustStem(gReturnVal) + C_MACEXT + "." + JustExt(gReturnVal)
  840.                     ENDIF
  841.                 ENDIF
  842.  
  843.                 SET MESSAGE TO C_PROJTASK1_LOC
  844.  
  845.  
  846.                 lHandled = .T.            && it's been dealt with?
  847.  
  848.  
  849.             CASE m.cConvType = C_PROJECTTYPEPARM OR ;
  850.                     m.cConvType = C_CATALOGTYPEPARM
  851.                 *- a project or catalog
  852.  
  853.                 LOCAL theClass, cFileType, lMakeBackDir, cobjname, cCvtMsg
  854.                 PRIVATE cFileName
  855.  
  856.                 cFileName = THIS.aConvParms[4]
  857.                 lMakeBackDir = .T.
  858.  
  859.                 *- always show "both platforms" option if project...
  860.                 THIS.aConvParms[12] = 2
  861.                 
  862.                 cCvtMsg = C_CONVERT4_LOC
  863.  
  864.                 DO CASE
  865.                     CASE m.cConvType = C_PROJECTTYPEPARM AND THIS.aConvParms[3] = "3.0"
  866.                         *- FP 3.x project
  867.                         m.theClass = THIS.pjxConverterClass
  868.                         m.cFileType = C_CONVERT3p_LOC
  869.                         m.cobjname = "cvtalertpjx3"
  870.                         cCvtMsg = C_CONVERT2_LOC
  871.                     CASE m.cConvType = C_PROJECTTYPEPARM
  872.                         *- FP 2.x project
  873.                         m.theClass = THIS.pjxConverterClass
  874.                         m.cFileType = C_CONVERT3p_LOC
  875.                         m.cobjname = "cvtalertpjx"
  876.                     CASE m.cConvType = C_CATALOGTYPEPARM AND THIS.aConvParms[3] = C_FOXVERSIONPARM
  877.                         *- FP 2.6 catalog
  878.                         m.theClass = THIS.fpcConverterClass
  879.                         m.cFileType = C_CONVERT3c_LOC
  880.                         m.cobjname = "cvtalertpjx"
  881.                     CASE m.cConvType = C_CATALOGTYPEPARM AND THIS.aConvParms[3] = C_DB4VERSIONPARM
  882.                         *- dBASE IV catalog
  883.                         lMakeBackDir = .F.
  884.                         m.theClass = THIS.db4CatConverterClass
  885.                         m.cFileType = C_CONVERT3c_LOC
  886.                         m.cobjname = "cvtalertcat"
  887.                     OTHERWISE
  888.                         *- ? error -- bad parm
  889.                         RETURN
  890.                 ENDCASE
  891.  
  892.                 *- verify user wants to convert
  893.                 IF !THIS.GetOpts(m.cobjname, C_CONVERT3_LOC + m.cFileType + PARTIALFNAME(SYS(2027,pFileName),C_FILELEN) + m.cCvtMsg)
  894.                     RETURN
  895.                 ENDIF
  896.  
  897.                 m.gOTherm = CREATEOBJ(C_THERMCLASS2,C_THERMTITLE_LOC, "", 0, 0,;
  898.                     C_THERMMSG1_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  899.                 gOTherm.Update(0)
  900.  
  901.                 =ACOPY(THIS.aConvParms,aParms)
  902.                 oConvObject = CREATE(m.theClass, @aParms)
  903.  
  904.                 IF TYPE("oConvObject") # 'O' OR THIS.lHadError
  905.                     *- object was not created
  906.                     THIS.lHadError = .T.
  907.                     RETURN
  908.                 ENDIF
  909.                 
  910.                 IF oConvObject.lHadError
  911.                     *- error creating converter object: 
  912.                     *- assume error has already been presented to user
  913.                     THIS.lHadError = .T.
  914.                     RELEASE oConvObject
  915.                     RETURN
  916.                 ENDIF
  917.  
  918.                 SET MESSAGE TO C_PROJTASK4_LOC
  919.  
  920.                 gReturnVal = oConvObject.Converter()
  921.  
  922.                 RELEASE oConvObject
  923.  
  924.                 lHandled = .T.            && it's been dealt with?
  925.                 
  926.             CASE m.cConvType = C_REPORTTYPEPARM
  927.  
  928.                 *- verify user wants to convert
  929.                 IF !THIS.GetOpts("cvtalertfrx",C_CONVERT3_LOC + ;
  930.                     IIF(JUSTEXT(THIS.aConvParms[4]) = "LBX",C_CONVERT3l_LOC,C_CONVERT3r_LOC) + ;
  931.                     PARTIALFNAME(THIS.aConvParms[4],C_FILELEN) + C_CONVERT2_LOC)
  932.                     RETURN
  933.                 ENDIF
  934.  
  935.                 THIS.aConvParms[1] = ""            && this was filled in by GetOpts -- clear so it causes no problems later
  936.                 =ACOPY(THIS.aConvParms,aParms)
  937.  
  938.                 gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  939.                     C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  940.                 gOTherm.Update(0)
  941.  
  942.                 oConvObject = CREATE(THIS.frxConverterClass, @aParms, .T.)
  943.  
  944.                 IF TYPE("oConvObject") # 'O'
  945.                     *- object was not created
  946.                     THIS.lHadError = .T.
  947.                     RETURN
  948.                 ENDIF
  949.                 
  950.                 IF oConvObject.lHadError
  951.                     *- error creating converter object: 
  952.                     *- assume error has already been presented to user
  953.                     oConvObject = .NULL.
  954.                     RELEASE oConvObject
  955.                     THIS.lHadError = .T.
  956.                     RETURN
  957.                 ENDIF
  958.                 
  959.                 IF oConvObject.lConverted
  960.                     *- file was transported from one 3.0 platform to another
  961.                     gReturnVal = oConvObject.cFRX2files
  962.                     RETURN
  963.                 ENDIF
  964.  
  965.                 SET MESSAGE TO C_PROJTASK2_LOC
  966.  
  967.                 gReturnVal = oConvObject.Converter()
  968.  
  969.                 RELEASE oConvObject
  970.  
  971.                 lHandled = .T.            && it's been dealt with?
  972.  
  973.             
  974.             CASE m.cConvType = C_LABELTYPEPARM
  975.             
  976.             CASE m.cConvType = C_MENUTYPEPARM
  977.             
  978.             CASE m.cConvType = C_DB4QUERYTYPEPARM
  979.             
  980.             CASE m.cConvType = C_DB4FORMTYPEPARM
  981.             
  982.             CASE m.cConvType = C_DB4REPORTTYPEPARM
  983.             
  984.             CASE m.cConvType = C_DB4LABELTYPEPARM
  985.             
  986.             CASE m.cConvType = C_FMTTYPEPARM
  987.                         
  988.                 m.gOTherm = CREATEOBJ(C_THERMCLASS1,C_THERMTITLE_LOC, ;
  989.                     C_THERMMSG3_LOC + LOWER(PARTIALFNAME(THIS.aConvParms[4],C_FILELEN)))
  990.                 gOTherm.Update(0)
  991.  
  992.                 =ACOPY(THIS.aConvParms,aParms)
  993.                 oConvObject = CREATE(THIS.fmtConverterClass, @aParms)
  994.                 IF TYPE("oConvObject") # 'O'
  995.                     *- object was not created
  996.                     THIS.lHadError = .T.
  997.                     RETURN
  998.                 ENDIF
  999.                 
  1000.                 IF oConvObject.lHadError
  1001.                     *- error creating SCX object: 
  1002.                     *- assume error has already been presented to user
  1003.                     THIS.lHadError = .T.
  1004.                     RELEASE oConvObject
  1005.                     RETURN
  1006.                 ENDIF
  1007.  
  1008.                 gReturnVal = oConvObject.Converter()
  1009.  
  1010.                 RELEASE oConvObject
  1011.  
  1012.                 lHandled = .T.            && it's been dealt with?
  1013.  
  1014.             CASE m.cConvType = C_FPLUSFRXTYPEPARM
  1015.             
  1016.  
  1017.         ENDCASE
  1018.  
  1019.     ENDPROC        &&  DoConvert
  1020.  
  1021.     *----------------------------------
  1022.     FUNCTION GetOpts        && masterconvert
  1023.     *----------------------------------
  1024.         *- display confirmation dialog, with options
  1025.         PARAMETER objname,cMsg
  1026.  
  1027.         PRIVATE oAlert, cBackDir, cLogFile, cCodeFile, lLog, lDevMode, lBackUp
  1028.         PRIVATE nOptDev, nCvt, iPlatformCount
  1029.  
  1030.         STORE "" TO cBackDir, cLogFile, cCodeFile
  1031.         STORE .F. TO lLog, lDevMode
  1032.         lBackup = .T.
  1033.         iBothPlat = 0
  1034.  
  1035.         m.cBackDir = ADDBS(JUSTPATH(THIS.aConvParms[4]))
  1036.  
  1037.         nOptDev = 1
  1038.         nCvt = 0
  1039.         oAlert = CREATEOBJ(m.objname,cMsg)
  1040.         IF TYPE("oAlert.chkBothPlat") == "O"
  1041.             oAlert.chkBothPlat.Enabled = (THIS.aConvParms[12] > 1)
  1042.         ENDIF
  1043.         IF TYPE("oAlert.chkSet30Def") == "O"
  1044.             oAlert.chkSet30Def.Enabled = .T.
  1045.         ENDIF
  1046.         oAlert.Show
  1047.         oAlert = .NULL.
  1048.         RELEASE oALert
  1049.         IF m.nCvt # 1
  1050.             RETURN .F.
  1051.         ENDIF
  1052.         THIS.aConvParms[ 7] = m.lDevMode        && developer mode
  1053.         THIS.aConvParms[ 8] = m.cCodeFile        && code file if dev mode
  1054.         THIS.aConvParms[ 9] = m.llog            && create log file?
  1055.         THIS.aConvParms[10] = m.cLogFile        && logfile name
  1056.         THIS.aConvParms[ 1] = m.cBackDir        && backup directory
  1057.         THIS.aConvParms[11] = m.lBackup            && make backup
  1058.         THIS.aConvParms[12] = m.iBothPlat + 1    && only convert screen records for current platform
  1059.     ENDFUNC
  1060.  
  1061.     *----------------------------------
  1062.     FUNCTION GetVersion
  1063.     *----------------------------------
  1064.         RETURN C_CONVERSION_LOC
  1065.  
  1066.     ENDFUNC
  1067.  
  1068.         
  1069. ENDDEFINE        &&  MasterConvert
  1070.  
  1071.  
  1072. **********************************************
  1073. DEFINE CLASS ConverterBase AS Cvt
  1074. **********************************************
  1075. *- This is the abstract base class for all converter 
  1076. *- objects. A converter object converts a particular
  1077. *- item, e.g., a project, a screen, etc.
  1078.  
  1079.     *- global instance variables
  1080.     nTimeStamp = 0 
  1081.  
  1082.     old25file = ""            && old 2.5 file name
  1083.     c25alias = ""            && old 2.5/2.6 alias
  1084.     cNew30File = ""            && new 3.0 file name
  1085.     new30alias = ""            && new 3.0 file alias  (or 4.0 for PJX)
  1086.  
  1087.     platonly = ""            && platform only option (Windows)
  1088.     oldfiletype = ""        && file type
  1089.     oldfilever = ""            && file version
  1090.     platform = C_ALL        && platform name
  1091.  
  1092.     cSetSkip = ""            && SET SKIP TO commands
  1093.     lAutoOpen = .F.            && Auto open tables in dataenvironment?
  1094.     lAutoClose = .F.        && Auto close tables in dataenvironment?
  1095.  
  1096.     lTransDlog = .F.        && Force the transporter dialog to show
  1097.  
  1098.     DIMENSION a_dimes[1]    && arrays that need to be "externalized"
  1099.     a_dimes = ""
  1100.  
  1101.     *- these are used by most of the children, so put here
  1102.     nDeffont1 = 1     && default screen FONT(1) -- height
  1103.     nDeffont5 = 0     && default screen FONT(5) -- extra leading
  1104.     nDeffont6 = 1     && default screen FONT(1) -- width
  1105.     cDefcolor = ""    && default background color
  1106.  
  1107.     nRecCount = 0
  1108.     nTmpCount = 1
  1109.  
  1110.     lBackup = .F.                && backup files (as .S2X, .S2T)
  1111.     iPlatformCount = 1            && only convert records for current platform
  1112.  
  1113.     *------------------
  1114.     PROCEDURE PreForm
  1115.     *------------------
  1116.         *- this is an external hook to preprocess
  1117.         *- form object via subclassing
  1118.     ENDPROC
  1119.  
  1120.     *------------------
  1121.     PROCEDURE PostForm
  1122.     *------------------
  1123.         *- this is an external hook to postprocess
  1124.         *- form object via subclassing
  1125.         
  1126.     ENDPROC
  1127.  
  1128.     *------------------------------------
  1129.     FUNCTION TStamp
  1130.     *------------------------------------
  1131.         * Generates a FoxPro 2.5-style timestamp
  1132.         PARAMETER wzpdate,wzptime
  1133.         PRIVATE d,t
  1134.  
  1135.         m.d = IIF(EMPTY(m.wzpdate),DATE(),m.wzpdate)
  1136.         m.t = IIF(EMPTY(m.wzptime),TIME(),m.wzptime)
  1137.  
  1138.         RETURN ((YEAR(m.d)-1980) * 2 ** 25);
  1139.          + (MONTH(m.d)           * 2 ** 21);
  1140.          + (DAY(m.d)             * 2 ** 16);
  1141.          + (VAL(LEFT(m.t,2))     * 2 ** 11);
  1142.          + (VAL(SUBSTR(m.t,4,2)) * 2 **  5);
  1143.          +  VAL(RIGHT(m.t,2))
  1144.     ENDFUNC        &&  TStamp
  1145.     
  1146.     *---------------------------
  1147.     FUNCTION AddQuotes
  1148.     *---------------------------
  1149.         PARAMETER pstring
  1150.         DO CASE
  1151.         CASE AT('"',m.pstring) = 0
  1152.             RETURN '"' + m.pstring + '"'    
  1153.         CASE AT("'",m.pstring) = 0
  1154.             RETURN "'" + m.pstring + "'"    
  1155.         OTHERWISE
  1156.             RETURN '[' + m.pstring + ']'    
  1157.         ENDCASE
  1158.     ENDFUNC
  1159.  
  1160.     *---------------------------
  1161.     FUNCTION AddProp
  1162.     *---------------------------
  1163.  
  1164.         *- Adds property to property list
  1165.         *- Converts if necessary
  1166.         *- Parameters:
  1167.         *-    fp30prop - property name
  1168.         *-    fp25fld - 2.5 field contents
  1169.         *-    fp30parent - parent reference (optional if needed)
  1170.         PARAMETER fp30prop,fp25fld,fp30parent
  1171.  
  1172.         IF INLIST(m.fp30prop,;
  1173.                     M_BACKCOLOR,;
  1174.                     M_MODE,;
  1175.                     M_PENSIZE,;
  1176.                     M_FONTBOLD)
  1177.             IF THIS.IsDefault(fp30prop,m.fp25fld)
  1178.                 RETURN
  1179.             ENDIF
  1180.         ENDIF
  1181.  
  1182.         DO CASE
  1183.             CASE EMPTY(m.fp30prop)
  1184.                 RETURN
  1185.                 
  1186.             CASE TYPE('m.fp25fld') = "C"
  1187.                 DO CASE
  1188.                     CASE LEN(m.fp25fld)=0
  1189.                         RETURN
  1190.                     CASE INLIST(m.fp30prop,;
  1191.                         M_PEN,;
  1192.                         M_BACKCOLOR,;
  1193.                         M_FILLCOLOR,;
  1194.                         M_DISFORECOLOR,;
  1195.                         M_DISBACKCOLOR,;
  1196.                         M_ITEMFORECOLOR,;
  1197.                         M_ITEMBACKCOLOR,;
  1198.                         M_DISITEMFORECOLOR,;
  1199.                         M_DISITEMBACKCOLOR,;
  1200.                         M_SELITEMBACKCOLOR,;
  1201.                         M_BORDERCOLOR,;
  1202.                         M_FPICTURE,;
  1203.                         M_ICON)
  1204.                         m.fp25fld = ALLTRIM(m.fp25fld)
  1205.                     CASE INLIST(m.fp30prop,;
  1206.                         M_FONTFACE,;
  1207.                         M_NAME,;
  1208.                         M_DATASOURCE,;
  1209.                         M_ALIAS,;
  1210.                         M_ORDER,;
  1211.                         M_CHILDALIAS,;
  1212.                         M_CHILDINDEXTAG,;
  1213.                         M_PARENTALIAS,;
  1214.                         M_PARENTINDEXEXPR,;
  1215.                         M_INITIALALIAS,;
  1216.                         M_ASSOCWINDS)
  1217.                         *- catch indirect references here
  1218.                           m.fp25fld = IIF(LEFT(ALLTRIM(m.fp25fld),1) = "(",;
  1219.                               ALLTRIM(m.fp25fld),;
  1220.                               THIS.addquotes(ALLTRIM(m.fp25fld)))
  1221.                     CASE INLIST(m.fp30prop,;
  1222.                             M_CURSORSRC)
  1223.                         m.fp25fld = ALLTRIM(m.fp25fld)
  1224.                     CASE INLIST(m.fp30prop,;
  1225.                             M_CAPTION,;
  1226.                             M_VALUE) AND LEFT(m.fp25fld,1) $ ["'[]
  1227.                         *- an expression in a label/say
  1228.                         *- or a value that needs parens
  1229.                         m.fp25fld = "(" + ALLTRIM(m.fp25fld) + ")"
  1230.                     CASE INLIST(m.fp30prop,;
  1231.                             M_CAPTION) OR AT(LEFT(m.fp25fld,1),["'[]) # 0
  1232.                         m.fp25fld = ALLTRIM(m.fp25fld)
  1233.                     OTHERWISE
  1234.                         m.fp25fld = "(" + ALLTRIM(m.fp25fld) + ")"
  1235.                 ENDCASE
  1236.             CASE TYPE('m.fp25fld') = "N"
  1237.                 m.fp25fld= ALLTRIM(STR(m.fp25fld))
  1238.             CASE TYPE('m.fp25fld') = "L"
  1239.                 m.fp25fld= IIF(m.fp25fld,".T.",".F.")
  1240.             CASE TYPE('m.fp25fld') = "D"
  1241.                 m.fp25fld= "{" + DTOC(m.fp25fld) + "}"
  1242.         ENDCASE
  1243.         
  1244.         IF TYPE('m.fp30parent')='C' AND !EMPTY(m.fp30parent)
  1245.             m.fp30prop = m.fp30parent + "." + m.fp30prop
  1246.         ENDIF
  1247.  
  1248.         IF LEN(m.fp25Fld) > 254        && RED00N4G
  1249.             *- changed action here -- now logs error and continues on
  1250.             THIS.WriteLog(E_WARNING_LOC,E_PROPTOOLONG_LOC + ALLTRIM(STR(recno())))
  1251.             IF TYPE("oForm.cCurrentFile") == 'C'
  1252.                 =MESSAGEBOX(E_WARNING_LOC + " - " + E_PROPTOOLONG_LOC + ALLTRIM(STR(recno())) + ;
  1253.                 ', ' + ALLT(oForm.cCurrentFile) + '.' + E_EXPRNOCONV_LOC + E_SEELOGFILE_LOC)
  1254.             ELSE
  1255.                 =MESSAGEBOX(E_WARNING_LOC + " - " + E_PROPTOOLONG_LOC + ALLTRIM(STR(recno())) + '.' + ;
  1256.                 E_EXPRNOCONV_LOC+ E_SEELOGFILE_LOC)
  1257.             ENDIF
  1258.             *- oForm.lHadError = .T.
  1259.             RETURN
  1260.         ENDIF
  1261.         
  1262.         THIS.fp3prop = THIS.fp3prop + ;
  1263.             m.fp30prop + C_SEP + m.fp25fld + C_CRLF
  1264.  
  1265.         RETURN
  1266.         
  1267.     ENDFUNC        && AddProp
  1268.     
  1269.     *---------------------------
  1270.     FUNCTION IsDefault
  1271.     *---------------------------
  1272.         PARAMETER cProp,cValue
  1273.  
  1274.         DO CASE
  1275.             CASE TYPE('m.cValue') = "N"
  1276.                 m.cValue = ALLT(STR(cValue))
  1277.             CASE TYPE('m.cValue') = "L"
  1278.                 m.cValue = IIF(cValue,".T.",".F")
  1279.         ENDCASE
  1280.  
  1281.         DO CASE
  1282.             CASE cProp = M_BACKCOLOR
  1283.                 RETURN .F.
  1284.                 *RETURN (cValue == "255,255,255")
  1285.             CASE cProp = M_MODE
  1286.                 RETURN (cValue == "1")
  1287.             CASE cProp = M_PENSIZE
  1288.                 RETURN (cValue == "1")
  1289.             CASE cProp = M_FONTBOLD
  1290.                 RETURN (cValue == ".T.")
  1291.             OTHERWISE
  1292.                 RETURN .F.
  1293.         ENDCASE
  1294.  
  1295.     ENDFUNC
  1296.  
  1297.     *---------------------------
  1298.     FUNCTION ClearProp
  1299.     *---------------------------
  1300.         *- clear accumulated properties
  1301.         THIS.fp3prop = ""
  1302.         
  1303.     ENDFUNC        && ClearProp
  1304.  
  1305.     *------------------------------------
  1306.     FUNCTION AddMethods            && ConverterBase
  1307.     *------------------------------------
  1308.         PARAMETER newmethod,fp25fld,ctype,newprop
  1309.         *- newmethod - method if procedure
  1310.         *- ctype= 0 -> Expression
  1311.         *- ctype= 1 -> Proc
  1312.         *- newprop - property if expression
  1313.         *- if newprop empty used newmethod
  1314.  
  1315.         LOCAL cTmp, savearea, gendir, m.newmethod2, m.gendircount
  1316.  
  1317.  
  1318.         IF EMPTY(ALLT(m.fp25fld))
  1319.           RETURN
  1320.         ENDIF
  1321.  
  1322.         IF m.ctype = 0    && expression used
  1323.             IF PARAMETERS() > 3 && expression with property
  1324.                 THIS.AddProp(m.newprop,m.fp25fld)
  1325.                 RETURN
  1326.             ENDIF
  1327.             *- check for GENSCRN tricks
  1328.             IF INLIST(UPPER(LEFT(ALLTRIM(m.fp25fld),3)),".T.",".F.") ;
  1329.                 AND LEN(ALLTRIM(m.fp25fld)) > 3
  1330.                 m.fp25fld = LEFT(ALLTRIM(m.fp25fld),3) + ;
  1331.                     " " + CHR(38) + CHR(38) + SUBSTR(ALLTRIM(m.fp25fld),4)
  1332.             ENDIF
  1333.             IF "SYS(16" $ UPPER(m.fp25fld)
  1334.                 m.fp25fld = STRTRAN(m.fp25fld,"SYS(16","_SYS(16")
  1335.                 m.fp25fld = STRTRAN(m.fp25fld,"sys(16","_sys(16")
  1336.                 m.fp25fld = STRTRAN(m.fp25fld,"Sys(16","_Sys(16")
  1337.             ENDIF
  1338.             m.fp25fld = "RETURN " +  m.fp25fld
  1339.         ENDIF
  1340.  
  1341.         m.savearea = SELECT()
  1342.         
  1343.         REPLACE _FOX3SPR.temp1 WITH m.fp25fld
  1344.         REPLACE _FOX3SPR.temp4 WITH CleanWhite(_FOX3SPR.temp1)
  1345.         SELECT _FOX3SPR
  1346.         THIS.FindArry
  1347.  
  1348.         *- comment out #REGION directives
  1349.         DO WHILE .T.
  1350.             m.gendir = MemoFind("#REGI","temp4",.T.,.F.,.F.,.F.,.T.)
  1351.             IF m.gendir = C_NULL
  1352.                 EXIT
  1353.             ENDIF
  1354.  
  1355.             *- Comment out directive
  1356.             _MLINE = 0
  1357.             nLine = MemoFind("#REGI","temp4",.T.,.T.,m.gendircount,.F.,.T.)
  1358.             cTmp = MLINE(temp1,nLine - 1)                        && set _MLINE
  1359.             REPLACE temp1 WITH STUFF(temp1,_MLINE + IIF(nLine <= 1,0,2),0,'*')
  1360.             cTmp = MLINE(temp4,nLine - 1)                        && set _MLINE
  1361.             REPLACE temp4 WITH STUFF(temp4,_MLINE + IIF(nLine <= 1,0,1),0,'*')
  1362.         ENDDO
  1363.         m.fp25fld = temp1
  1364.  
  1365.         IF USED(THIS.c25alias)
  1366.             SELECT (THIS.c25alias)
  1367.         ELSE
  1368.             SELECT (m.savearea)
  1369.         ENDIF
  1370.  
  1371.         *- see if multiple procs in the procedure section
  1372.         *- if so, strip out and move to .SPR file, since 3.0
  1373.         *- won't expect more than one proc in a method...
  1374.         *- there's no PROC or FUNC line for the VALID
  1375.         IF INLIST(m.newmethod,;
  1376.                     M_VALID,;
  1377.                     M_VALID2,;
  1378.                     M_ERROR,;
  1379.                     M_MESSAGE,;
  1380.                     M_ACTIVATE,;
  1381.                     M_DEACTIVATE,;
  1382.                     M_SHOW,;
  1383.                     M_WHEN,;
  1384.                     M_WHEN2)
  1385.             m.cTmp = UPPER(m.fp25fld)
  1386.             IF OCCURS("PROC",m.cTmp) + OCCURS("FUNC",m.cTmp) > 0
  1387.                 *- get other procs, and put them in SPR file
  1388.                 *- use correct field name
  1389.                 m.newmethod2 = IIF(UPPER(LEFT(m.newmethod,4)) = "READ",SUBS(m.newmethod,5),;
  1390.                                 IIF(UPPER(LEFT(m.newmethod,5)) = "ERROR",LEFT(m.newmethod,5),m.newmethod))
  1391.                 DO extractprocs WITH 0,m.newmethod2
  1392.                 *- Move the stuff to a holding place for now
  1393.                 IF !EMPTY(_FOX3SPR.sprmemo) AND m.newmethod # M_SHOW
  1394.                     REPLACE _FOX3SPR.temp3 WITH C_CRLF + _FOX3SPR.sprmemo ADDITIVE
  1395.                     REPLACE _FOX3SPR.sprmemo WITH ""
  1396.                 ENDIF
  1397.                 IF INLIST(m.newmethod,;
  1398.                     M_VALID2,;
  1399.                     M_WHEN2)
  1400.                     *- throw away everything up to first PROC or FUNC
  1401.                     LOCAL iFunc,iProc
  1402.                     cTmp = C_CR + STRTRAN(m.fp25fld,C_CRLF,C_CR)
  1403.                     iFunc = AT(C_CR + "FUNC",cTmp)
  1404.                     iProc = AT(C_CR + "PROC",cTmp)
  1405.                     iFunc = IIF(iFunc = 0,99999999,iFunc)
  1406.                     iProc = IIF(iProc = 0,99999999,iProc)
  1407.                     m.fp25fld = SUBS(cTmp,2,MIN(iFunc, iProc) - 2)    && we added a CR at the beginning
  1408.                 ENDIF
  1409.             ENDIF
  1410.         ENDIF
  1411.         *- Add method code to fp3method
  1412.         IF !EMPTY(m.fp25fld)
  1413.             THIS.fp3method = THIS.fp3method + ;
  1414.                 "PROCEDURE " + m.newmethod + C_CRLF + ;
  1415.                     m.fp25fld + IIF(RIGHT(m.fp25fld,2) = C_CRLF OR ;
  1416.                      RIGHT(m.fp25fld,1) = C_CR,"",C_CRLF) + ;
  1417.                 "ENDPROC" + C_CRLF + C_CRLF
  1418.         ENDIF
  1419.         
  1420.         SELECT (m.savearea)
  1421.  
  1422.         RETURN
  1423.     ENDFUNC        && ConverterBase:AddMethods
  1424.  
  1425.  
  1426.     *--------------------------------------
  1427.     FUNCTION FindArry        && ConverterBase
  1428.     *--------------------------------------
  1429.         *- look for DIMENSION or DECLARE, and add to list a_Dimes list, so they
  1430.         *- can be "externalized" in the .SPR file
  1431.  
  1432.         *- assume that code to be searched is in _FOX3SPR.temp1, and that table
  1433.         *- is open in the current work area
  1434.         *- also, code in temp4 is stripped of leading white space
  1435.  
  1436.         LOCAL m.nArryCt, m.cArryName, m.nArryLen, m.j, m.iPlace, m.cTemp, m.nCtr
  1437.  
  1438.         m.nArryCt = 1
  1439.         DO WHILE .T.
  1440.             m.cArryName = UPPER(MemoFind("DECL","temp4",.T.,.F.,m.nArryCt,.T.,.T.))
  1441.             IF m.cArryName = C_NULL
  1442.                 EXIT
  1443.             ENDIF
  1444.             IF RIGHT(TRIM(m.cArryName),1) = ";"
  1445.                 *- a continued DECLARE, so take some special measures
  1446.                 m.cArryName = ""
  1447.                 iPlace = MemoFind("DECL","temp4",.T.,.T.,m.nArryCt,.T.,.T.)
  1448.                 IF m.iPlace = 0
  1449.                     *- this should be an impossibility -- couldn;t find where it was
  1450.                     EXIT
  1451.                 ENDIF
  1452.                 cTemp = MLINE(temp1,m.iPlace)
  1453.                 *- check for continued DECLARE
  1454.                 m.nCtr = 1
  1455.                 DO WHILE .T.
  1456.                     m.cArryName = m.cArryName + m.cTemp
  1457.                     IF RIGHT(m.cTemp,1) # ";"
  1458.                         EXIT
  1459.                     ELSE
  1460.                         m.cTemp = MLINE(temp1,m.iPlace + m.nCtr)
  1461.                         m.nCtr = m.nCtr + 1
  1462.                     ENDIF
  1463.                 ENDDO
  1464.                 m.cArryName = STRTRAN(SUBS(m.cArryName,AT("DECL",UPPER(m.cArryName)) + 4),";","")
  1465.             ENDIF
  1466.             m.nArryCt = m.nArryCt + 1
  1467.             m.nArryLen = ALEN(THIS.a_Dimes)
  1468.             IF !EMPTY(THIS.a_Dimes[1])
  1469.                 DIMENSION THIS.a_Dimes[m.nArryLen + 1]
  1470.                 m.nArryLen = m.nArryLen + 1
  1471.             ENDIF
  1472.             IF  UPPER(LEFT(m.cArryName,2)) == "A " OR ;
  1473.                 UPPER(LEFT(m.cArryName,3)) == "AR " OR ;
  1474.                 UPPER(LEFT(m.cArryName,4)) == "ARE "
  1475.                 THIS.a_Dimes[m.nArryLen] = SUBS(m.cArryName,AT(' ',m.cArryName) + 1)
  1476.             ELSE
  1477.                 THIS.a_Dimes[m.nArryLen] = m.cArryName
  1478.             ENDIF
  1479.         ENDDO
  1480.         m.nArryCt = 1
  1481.         DO WHILE .T.
  1482.             m.cArryName = UPPER(MemoFind("DIME","temp4",.T.,.F.,m.nArryCt,.T.,.T.))
  1483.             IF m.cArryName = C_NULL
  1484.                 EXIT
  1485.             ENDIF
  1486.             IF RIGHT(TRIM(m.cArryName),1) = ";"
  1487.                 *- a continued DECLARE, so take some special measures
  1488.                 m.cArryName = ""
  1489.                 iPlace = MemoFind("DIME","temp4",.T.,.T.,m.nArryCt,.T.,.T.)
  1490.                 IF m.iPlace = 0
  1491.                     *- this should be an impossibility -- couldn;t find where it was
  1492.                     EXIT
  1493.                 ENDIF
  1494.                 cTemp = MLINE(temp1,m.iPlace)
  1495.                 *- check for continued DECLARE
  1496.                 m.nCtr = 1
  1497.                 DO WHILE .T.
  1498.                     m.cArryName = m.cArryName + m.cTemp
  1499.                     IF RIGHT(m.cTemp,1) # ";"
  1500.                         EXIT
  1501.                     ELSE
  1502.                         m.cTemp = MLINE(temp1,m.iPlace + m.nCtr)
  1503.                         m.nCtr = m.nCtr + 1
  1504.                     ENDIF
  1505.                 ENDDO
  1506.                 m.cArryName = STRTRAN(SUBS(m.cArryName,AT("DIME",UPPER(m.cArryName)) + 4),";","")
  1507.             ENDIF
  1508.             m.nArryCt = m.nArryCt + 1
  1509.             m.nArryLen = ALEN(THIS.a_Dimes)
  1510.             IF !EMPTY(THIS.a_Dimes[1])
  1511.                 DIMENSION THIS.a_Dimes[m.nArryLen + 1]
  1512.                 m.nArryLen = m.nArryLen + 1
  1513.             ENDIF
  1514.             IF  UPPER(LEFT(m.cArryName,2)) == "N " OR ;
  1515.                 UPPER(LEFT(m.cArryName,3)) == "NS " OR ;
  1516.                 UPPER(LEFT(m.cArryName,4)) == "NSI " OR ;
  1517.                 UPPER(LEFT(m.cArryName,5)) == "NSIO " OR ;
  1518.                 UPPER(LEFT(m.cArryName,6)) == "NSION "
  1519.                 THIS.a_Dimes[m.nArryLen] = SUBS(m.cArryName,AT(' ',m.cArryName) + 1)
  1520.             ELSE
  1521.                 THIS.a_Dimes[m.nArryLen] = m.cArryName
  1522.             ENDIF
  1523.         ENDDO
  1524.  
  1525.     ENDFUNC        && ConverterBase:FindArry
  1526.  
  1527.     *------------------------------------
  1528.     FUNCTION OpenFile        && ConverterBase
  1529.     *------------------------------------
  1530.         PARAMETER cFile
  1531.  
  1532.         PRIVATE cThisAlias
  1533.         LOCAL m.nfh
  1534.                 
  1535.         *- cFile is the file to open
  1536.         m.cThisAlias= "S" + LEFT(SYS(3),7)
  1537.  
  1538.         SELECT 0
  1539.         
  1540.         *- now try to open file
  1541.         IF FILE(m.cFile)
  1542.             DO CASE
  1543.                 CASE !Readable(m.cFile)
  1544.                     *- file is already open
  1545.                     THIS.WriteLog(JUSTFNAME(m.cFile),TRIM(E_FILE_LOC) + E_NOCONVERT2_LOC)
  1546.                     =MESSAGEBOX(E_NOOPEN_LOC + m.cFile + ". " + E_FILEOPEN_LOC)
  1547.                     THIS.lHadError = .T.
  1548.                 CASE pReadOnly(cFile)
  1549.                     *- if read only, we can;t do anything with it... (jd 04/15/95, RED00M77)
  1550.                     THIS.WriteLog(JUSTFNAME(m.cFile),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  1551.                     =MESSAGEBOX(TRIM(m.cFile) + E_NOCONVERT3_LOC)
  1552.                     THIS.lHadError = .T.
  1553.                 CASE THIS.IsDBF(m.cFile)
  1554.                     *- success
  1555.                     USE (m.cFile) ALIAS (m.cThisAlias) EXCLUSIVE
  1556.                 OTHERWISE
  1557.                     THIS.WriteLog(JUSTFNAME(m.cFile),E_INVALDBF_LOC)
  1558.                     =MESSAGEBOX(E_FILE_LOC + m.cFile + E_NOCONVERT2_LOC)
  1559.                     THIS.lHadError = .T.
  1560.             ENDCASE
  1561.         ELSE
  1562.             *- log the error
  1563.             THIS.WriteLog(JUSTFNAME(m.cFile),TRIM(E_FILE_LOC) + E_NOCONVERT1_LOC)
  1564.             =MESSAGEBOX(E_FILE_LOC + m.cFile + E_NOCONVERT1_LOC)
  1565.             THIS.lHadError = .T.
  1566.         ENDIF
  1567.  
  1568.         *- Check if had error opening file
  1569.         IF THIS.lHadError
  1570.             RETURN ""
  1571.         ENDIF
  1572.  
  1573.         RETURN m.cThisAlias
  1574.  
  1575.     ENDFUNC        && ConverterBase:OpenFile
  1576.     
  1577.  
  1578.     *------------------------------------
  1579.     FUNCTION GetVarPrefix        && ConverterBase
  1580.     *------------------------------------
  1581.         PARAMETER cClassType
  1582.  
  1583.         DO CASE
  1584.             CASE cClassType = T_LABEL
  1585.                 RETURN "lbl"
  1586.             CASE cClassType = T_SAY
  1587.                 RETURN "txt"
  1588.             CASE cClassType = T_EDIT
  1589.                 RETURN "edt"
  1590.             CASE cClassType = T_LINE
  1591.                 RETURN "lin"
  1592.             CASE cClassType = T_SHAPE
  1593.                 RETURN "shp"
  1594.             CASE cClassType = T_INV
  1595.                 RETURN "cmg"
  1596.             CASE cClassType = T_BTNGRP OR;
  1597.                 cClassType = T_BTN
  1598.                 RETURN "cmg"
  1599.             CASE cClassType = T_PICT
  1600.                 RETURN "img"
  1601.             CASE cClassType = T_RADIO
  1602.                 RETURN "opt"
  1603.             CASE cClassType = T_RADIOGRP
  1604.                 RETURN "opg"
  1605.             CASE cClassType = T_CBOX
  1606.                 RETURN "chk"
  1607.             CASE cClassType = T_POPUP
  1608.                 RETURN "cbo"
  1609.             CASE cClassType = T_SPIN
  1610.                 RETURN "spn"
  1611.             CASE cClassType = T_OLE
  1612.                 RETURN "ole"
  1613.             CASE cClassType = T_LIST
  1614.                 RETURN "lst"
  1615.             CASE cClassType = T_DATANAV
  1616.                 RETURN "de"
  1617.             CASE cClassType = T_CURSOR
  1618.                 RETURN "crs"
  1619.             CASE cClassType = T_RELATION
  1620.                 RETURN "rel"
  1621.             CASE cClassType = T_FSET
  1622.                 RETURN "frs"
  1623.             CASE cClassType = T_FORM
  1624.                 RETURN "frm"
  1625.             CASE cClassType = T_PAGE
  1626.                 RETURN "pgf"
  1627.             OTHERWISE
  1628.                 RETURN "c"
  1629.         ENDCASE
  1630.     ENDFUNC
  1631.  
  1632.     *------------------------------------
  1633.     FUNCTION Converter
  1634.     *------------------------------------
  1635.         *- this method should always be overridden
  1636.         WAIT WINDOW "Called Converter function that wasn't overridden!"
  1637.         RETURN -1
  1638.     ENDFUNC
  1639.     
  1640.     *------------------------------------
  1641.     FUNCTION ok2nuke
  1642.     *------------------------------------
  1643.         *- Emulate SAFETY ON
  1644.  
  1645.         PARAMETER cFileName
  1646.         LOCAL m.nresult
  1647.  
  1648.         DO CASE
  1649.             CASE _WINDOWS
  1650.                 RETURN MESSAGEBOX(UPPER(JustFName(m.cFileName)) + C_OVERWRITE_LOC,MB_YESNO) = IDYES
  1651.             OTHERWISE
  1652.                 *- not implemented yet
  1653.                 RETURN .F.
  1654.         ENDCASE
  1655.  
  1656.     ENDFUNC        && ok2nuke
  1657.  
  1658.     *----------------------------------
  1659.     PROCEDURE CompileFRX
  1660.     *----------------------------------
  1661.         *- take code from TAG field of DataEnvironment record, and 
  1662.         *- compile it as an FXP, then append it into the TAG2 field
  1663.         *- There is no "COMPILE REPORT" command
  1664.         *- Assume we are positioned on the appropriate record
  1665.         LOCAL cTmpFile
  1666.  
  1667.         cTmpFile = SYS(3) + ".PRG"
  1668.         
  1669.         IF !EMPTY(tag)
  1670.             COPY MEMO tag TO (cTmpFile)
  1671.             COMPILE (cTmpFile)
  1672.             IF !_mac
  1673.                 APPEND MEMO tag2 FROM (FORCEEXT(cTmpFile,"FXP"))
  1674.             ELSE
  1675.                 LOCAL iFH, iBuffer
  1676.                 iFH = FOPEN(FORCEEXT(cTmpFile,"FXP"))
  1677.                 IF iFH # -1
  1678.                     DO WHILE !FEOF(iFH)
  1679.                         iBuffer = FREAD(iFH, N_BUFFSZ)
  1680.                         REPLACE tag2 WITH iBuffer ADDITIVE
  1681.                     ENDDO
  1682.                     =FCLOSE(iFH)
  1683.                 ELSE
  1684.                     *- some kind of error
  1685.                 ENDIF
  1686.             ENDIF
  1687.             ERASE (cTmpFile)
  1688.             ERASE (FORCEEXT(cTmpFile,"FXP"))
  1689.         ENDIF
  1690.         RETURN
  1691.  
  1692.     ENDPROC        && CompileFRX
  1693.  
  1694.  
  1695. ENDDEFINE        &&  ConverterBase 
  1696.  
  1697.  
  1698. **********************************************
  1699. DEFINE CLASS PJXConverterBase AS ConverterBase
  1700. **********************************************
  1701.  
  1702.     *- methods that might be changed in a sub-classed
  1703.     scxConverterClass = "SCXSingleScreenConverter"
  1704.     scx30ConverterClass = "SCX30Converter"
  1705.     frxConverterClass = "FRXConverter"
  1706.  
  1707.     curscxid = 1        && project current setid
  1708.     highscxid = 0        && project high setid
  1709.     isproj = .T.
  1710.     cHomeDir = ""
  1711.     cBackDir = ""
  1712.     cOutFile = ""
  1713.     cStubFile = ""
  1714.     pjxName = ""
  1715.     pjx25Alias = ""        && 2.5 project alias
  1716.     pjxVersion = ""
  1717.     lIsMain = .F.
  1718.     lEncrypt = .F.
  1719.     lSaveCode = .T.        && saveCode option (6.8.96 jd)
  1720.     cDevInfo = ""
  1721.     lDebug = .F.
  1722.     lExclude = .F.
  1723.     nScreenSets = 0        && number of undeleted screen sets in project
  1724.     nScreenCtr = 0        && counter for screens actually converted
  1725.     cFull30PJXName = ""    && fully-qualifed name of new PJX
  1726.     f2Files = ""        && holder for 2.x FRX file name
  1727.     f3files = ""        && holder for 3.x FRX file name
  1728.     cMemoExt = ""        && extension for memo files for files of this type
  1729.  
  1730.     DIMENSION a_pjxsets[10]
  1731.  
  1732.     *----------------------------------
  1733.     PROCEDURE CreatePJX        && PJXConverterBase
  1734.     *----------------------------------
  1735.         PRIVATE cTmpPJXName
  1736.  
  1737.         m.cTmpPJXName = ADDBS(JUSTPATH(THIS.pjxName)) + "P" + LEFT(SYS(3),7) + ".PJX"
  1738.  
  1739.         *- create new PJX file
  1740.         CREATE TABLE (m.cTmpPJXName) ;
  1741.             (name        m,;
  1742.             type        c(1),;
  1743.             id            n(10),;
  1744.             timestamp   n(10),;
  1745.             outfile     m,;
  1746.             homedir     m,;
  1747.             exclude     l,;
  1748.             mainprog    l,;
  1749.             savecode    l,;
  1750.             debug       l,;
  1751.             encrypt     l,;
  1752.             nologo      l,;
  1753.             cmntstyle   n(1),;
  1754.             objrev      n(5),;
  1755.             devinfo     m,;
  1756.             symbols     m,;
  1757.             object      m,;
  1758.             ckval       n(6),;
  1759.             cpid        n(5),;
  1760.             ostype      c(4),;
  1761.             oscreator   c(4),;
  1762.             comments    m,;
  1763.             reserved1   m,;
  1764.             reserved2   m,;
  1765.             sccdata     m,;
  1766.             local       l,;
  1767.             key         c(32),;
  1768.             user        m)
  1769.  
  1770.         THIS.new30alias = ALIAS()
  1771.  
  1772.         *- Add header comment record  && added SaveCode (6.8.96 jd)
  1773.         INSERT INTO (THIS.new30alias) ;
  1774.             (name, timestamp, type, homedir, saveCode, objrev, debug, encrypt, devinfo);
  1775.             VALUES (JUSTFNAME(THIS.pjxName),THIS.nTimeStamp,;
  1776.                 "H", JUSTPATH(THIS.pjxName) + C_NULL, ;
  1777.                 THIS.lSaveCode, C_PJXVERSTAMP, THIS.lDebug, THIS.lEncrypt, THIS.cDevInfo)
  1778.         THIS.p30to40
  1779.         
  1780.     ENDPROC        &&   CreatePJX
  1781.  
  1782.     *----------------------------------
  1783.     PROCEDURE InsertSCX            && PJXConverterBase
  1784.     *----------------------------------
  1785.         *- add appropriate record(s) to 3.0 PJX file
  1786.         *- additional work is done in subclassed InsertSCX
  1787.         IF !THIS.lDevMode
  1788.             *- if Dev Mode (aka "Visual Conversion"), don;t need SPRs
  1789.             *- also add record for [new] SPR file
  1790.             INSERT INTO (THIS.new30alias) ;
  1791.                     (name,;
  1792.                     timestamp,;
  1793.                     type,;
  1794.                     exclude,;
  1795.                     mainprog,;
  1796.                     cpid,;
  1797.                     key);
  1798.                 VALUES(;
  1799.                     SYS(2014,THIS.cStubFile,DBF(THIS.new30alias)) + CHR(0),;
  1800.                     THIS.nTimeStamp,;
  1801.                     C_PRGTYPE,;
  1802.                     THIS.lExclude,;
  1803.                     THIS.lIsMain,;
  1804.                     IIF(CPCURRENT() # 0, CPCURRENT(),CPDBF(THIS.new30alias)),;
  1805.                     UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  1806.         ENDIF
  1807.  
  1808.     ENDPROC        && InsertSCX
  1809.  
  1810.     *------------------------------------
  1811.     PROCEDURE CloseFiles            && PJXConverterBase
  1812.     *------------------------------------
  1813.         IF USED(THIS.pjx25Alias)
  1814.             USE IN (THIS.pjx25Alias)
  1815.         ENDIF
  1816.  
  1817.         IF USED(THIS.new30alias)
  1818.             IF THIS.lLog
  1819.                 SELECT (THIS.new30alias)
  1820.                 IF TYPE("user") = "M"
  1821.                     GO TOP
  1822.                     REPLACE user WITH m.gLog + C_CRLF + C_LOGEND_LOC + " [" + TTOC(DATETIME()) + "]" + C_CRLF
  1823.                     COPY MEMO user TO (THIS.cLogFile)
  1824.                 ENDIF
  1825.             ENDIF
  1826.             USE IN (THIS.new30alias)
  1827.         ENDIF            
  1828.  
  1829.     ENDPROC
  1830.  
  1831.     *------------------
  1832.     PROCEDURE BackFiles
  1833.     *------------------
  1834.         PARAMETER cField, cType, cDesc
  1835.         PRIVATE cBackName,cTmpFname, m.cTmpFnameOld, m.lNoFinds, m.savearea,;
  1836.             cCurDir, i, nCvt
  1837.  
  1838.         LOCAL cOldPath, cNewPath, cThisPath, cFName
  1839.  
  1840.         *- make sure project file locations are up-to-date
  1841.         m.savearea = SELECT()
  1842.         SELECT (THIS.pjx25Alias)
  1843.  
  1844.         *- copy first time only
  1845.         IF !FILE(THIS.cBackDir + JUSTFNAME(THIS.cCurrentFile)) AND THIS.lBackUp
  1846.             COPY FILE (THIS.cCurrentFile) TO THIS.cBackDir + JUSTFNAME(THIS.cCurrentFile)
  1847.             COPY FILE (FORCEEXT(THIS.cCurrentFile,THIS.cMemoExt)) TO (FORCEEXT(THIS.cBackDir + JUSTFNAME(THIS.cCurrentFile),THIS.cMemoExt))
  1848.         ENDIF
  1849.  
  1850.         cOldPath = SET("PATH")
  1851.         cNewPath = m.cOldPath
  1852.         
  1853.         nCvt = 0
  1854.  
  1855.         SCAN FOR !(type $ 'SH') AND !DELETED()            && type $ m.cType AND !DELETED()
  1856.             cFName = ALLTRIM(IIF(AT(CHR(0),&cField) > 0,LEFT(&cField,AT(CHR(0),&cField)-1),&cField))
  1857.             IF !_MAC AND OCCURS(":",cFName) > 1
  1858.                 *- FULLPATH will fail on this path, and since it is invalid for DOS etc.,
  1859.                 *- translate ":" into "\" and let user find the files
  1860.                 cFName = STRTRAN(cFName,":","\")
  1861.             ENDIF
  1862.             cTmpFname = FULLPATH(cFName,THIS.cHomeDir)
  1863.             IF !FILE(cTmpFname)
  1864.                 *- it;s not in the place where it's supposed to be
  1865.                 *- is it in the path?
  1866.                 IF FILE(JustFName(cTmpFname))
  1867.                     *- let Fox find the correct path, in the SET PATH
  1868.                     m.cTmpFname = FULLPATH(JustFName(m.cTmpFname))
  1869.                 ELSE
  1870.                     *- try to locate file first
  1871.                     IF m.nCvt = 3
  1872.                         *- ignore all
  1873.                         THIS.WriteLog(cTmpFname,E_FILE_LOC + JustFName(cTmpFname) + E_NOCONVERT1_LOC)
  1874.                         LOOP
  1875.                     ENDIF
  1876.                     *- cvtLocate is based on the cvtAlertFrx. so it uses the same variables
  1877.                     oLocate = CREATEOBJECT("cvtLocate",C_LOCFILE3_LOC)
  1878.                     oLocate.Show
  1879.                     RELEASE oLocate
  1880.                     DO CASE
  1881.                         CASE m.nCvt = 1
  1882.                             *- locate
  1883.                             m.cTmpFnameOld = m.cTmpFname
  1884.                             m.cTmpFname = ""
  1885.                             THIS.lLocalErr = .T.
  1886.                             m.cTmpFname = LOCFILE(JUSTFNAME(m.cTmpFnameOld),JUSTEXT(m.cTmpFnameOld),C_LOCFILE2_LOC)
  1887.                             THIS.lLocalErr = .F.
  1888.                         CASE m.nCvt = 2 OR m.nCvt = 3
  1889.                             *- ignore
  1890.                             THIS.WriteLog(cTmpFname,E_FILE_LOC + JustFName(cTmpFname) + E_NOCONVERT1_LOC)
  1891.                             LOOP
  1892.                         OTHERWISE
  1893.                             *- cancel
  1894.                             m.cTmpFname = ""
  1895.                     ENDCASE
  1896.                 ENDIF
  1897.  
  1898.                 *- if found, update project
  1899.                 IF EMPTY(m.cTmpFname)
  1900.                     *- cancelled, so quit conversion
  1901.                     THIS.lHadError = .T.
  1902.                     RETURN
  1903.                 ELSE
  1904.                     REPLACE &cField WITH m.cTmpFname
  1905.                     *- and remember this location
  1906.                     m.cThisPath = JUSTPATH(cTmpFname)
  1907.                     IF !(m.cThisPath $ m.cNewPath)
  1908.                         cNewPath = m.cNewPath + "," + m.cThisPath
  1909.                         SET PATH TO &cNewPath
  1910.                     ENDIF
  1911.                 ENDIF
  1912.             ENDIF
  1913.  
  1914.         ENDSCAN
  1915.  
  1916.         *- restore path
  1917.         SET PATH TO &cOldPath
  1918.  
  1919.         SELECT (m.savearea)
  1920.         
  1921.         IF THIS.lBackUp
  1922.             gOTherm.Update2(0,C_BACKFILES_LOC)
  1923.         
  1924.             SELECT &cField, type FROM DBF(THIS.pjx25Alias) ;
  1925.                 WHERE type $ m.cType AND !DELETED() ;
  1926.                 INTO ARRAY tmparr
  1927.  
  1928.             IF _TALLY = 0
  1929.                 RETURN
  1930.             ENDIF
  1931.  
  1932.             m.lNoFinds = .F.
  1933.  
  1934.             FOR i = 1 TO _TALLY
  1935.                 *- Copy files to backup directory
  1936.                 m.cTmpFname = FULLPATH(ALLTRIM(IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  1937.                     LEFT(tmparr[m.i,1],AT(CHR(0),tmparr[m.i,1])-1),tmparr[m.i,1])),THIS.cHomeDir)
  1938.                 m.cBackName = THIS.cBackDir + JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL))
  1939.  
  1940.                 IF !FILE(m.cTmpFname)   && is file there?
  1941.                     *- if not there, log the error and continue
  1942.                     THIS.WriteLog(JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL)),E_NOFILE_LOC + TRIM(m.cDesc) + E_NOBACKUP_LOC)
  1943.                     m.lNoFinds = .T.
  1944.                     LOOP
  1945.                 ENDIF
  1946.  
  1947.                 IF !FILE(m.cBackName)   && check if file already copied over
  1948.                     COPY FILE (m.cTmpFname) TO (m.cBackName)
  1949.                     DO CASE
  1950.                         CASE tmparr[m.i,2] $ 'sK' OR tmparr[m.i,2] = 'scx'
  1951.                             *- assume screen/form
  1952.                             COPY FILE (FORCEEXT(m.cTmpFname,C_SCTEXT)) TO (FORCEEXT(m.cBackName,C_SCTEXT))
  1953.                         CASE tmparr[m.i,2] == 'V' OR tmparr[m.i,2] = 'vcx'
  1954.                             *- assume visual class
  1955.                             COPY FILE (FORCEEXT(m.cTmpFname,C_VCTEXT)) TO (FORCEEXT(m.cBackName,C_VCTEXT))
  1956.                         CASE tmparr[m.i,2] = 'R' OR tmparr[m.i,2] = 'frx'
  1957.                             *- assume report form
  1958.                             COPY FILE (FORCEEXT(m.cTmpFname,"FRT")) TO (FORCEEXT(m.cBackName,"FRT"))
  1959.                         CASE tmparr[m.i,2] $ 'B' OR tmparr[m.i,2] = 'lbx'
  1960.                             *- assume report form
  1961.                             COPY FILE (FORCEEXT(m.cTmpFname,"LBT")) TO (FORCEEXT(m.cBackName,"LBT"))
  1962.                     ENDCASE
  1963.                 ENDIF
  1964.             ENDFOR
  1965.             
  1966.             IF m.lNoFinds
  1967.                 IF MESSAGEBOX(E_NOFINDS_LOC,1) = IDCANCEL
  1968.                     gOMaster.lHadError = .T.
  1969.                 ENDIF
  1970.             ENDIF
  1971.  
  1972.         ENDIF        && THIS.lBackUp
  1973.  
  1974.  
  1975.     ENDPROC        && PJXConverterBase:BackFiles
  1976.     
  1977.     *----------------------------------
  1978.     PROCEDURE CompileAllScx            && PJXConverterBase
  1979.     *----------------------------------
  1980.         *- compile the SCX files in the converted project (save till end)
  1981.         LOCAL cFile, lIs30File, cPath, cErrFile
  1982.  
  1983.         THIS.WriteLog("","")
  1984.  
  1985.         SELECT (THIS.new30alias)
  1986.         
  1987.         cPATH = SET("PATH") + ',' + JustPath(THIS.pjxName)
  1988.         
  1989.         SCAN FOR type = C_SCXTYPE OR type = C_VCXTYPE
  1990.  
  1991.             m.lIs30File = .F.
  1992.  
  1993.             IF FILE(THIS.cHomeDir + STRTRAN(name,C_NULL,""))
  1994.                 cFile = THIS.cHomeDir + STRTRAN(name,C_NULL,"")
  1995.                 *- make sure file is converted and openable (maybe user bailed from transporting)
  1996.                 IF Readable(m.cFile) AND THIS.IsDBF(m.cFile)
  1997.                     SELECT 0
  1998.                     USE (m.cFile) EXCLUSIVE
  1999.                     IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  2000.                         *- okay -- it's a 3.0 file
  2001.                         m.lIs30File = .T.
  2002.                     ENDIF
  2003.                     USE
  2004.                     SELECT (THIS.new30alias)
  2005.                 ENDIF
  2006.                 IF m.lIs30File
  2007.                     THIS.WriteLog(SYS(2027,m.cFile),C_COMPILE_LOC)
  2008.                     THIS.lLocalErr = .T.
  2009.                     
  2010.                     cErrFile = AddBS(JustPath(m.cFile)) + JustStem(m.cFile) + ".ERR"
  2011.                     IF FILE(m.cErrFile)
  2012.                         ERASE (m.cErrFile)
  2013.                     ENDIF
  2014.                     
  2015.                     COMPILE FORM (m.cFile)                    
  2016.  
  2017.                     IF THIS.lHadLocErr OR FILE(m.cErrFile)
  2018.                         THIS.WriteLog(SYS(2027,m.cFile),E_NOINCLUDE_LOC)
  2019.                         =MESSAGEBOX(E_NOINCLUDE1_LOC + SYS(2027,m.cFile) + E_NOINCLUDE2_LOC)
  2020.                         THIS.lHadLocErr = .F.
  2021.                     ENDIF
  2022.                     THIS.lLocalErr = .F.
  2023.                 ENDIF
  2024.             ENDIF
  2025.         ENDSCAN
  2026.  
  2027.     ENDPROC        && PJXConverterBase:CompileAllScx
  2028.  
  2029. #if 0
  2030.     *------------------------------------
  2031.     PROCEDURE Error                && Cvt
  2032.     *------------------------------------
  2033.         PARAMETER errorNum, method, line
  2034.  
  2035.         IF errorNum = 1994
  2036.             *- can;t find .h file
  2037.             THIS.lHadLocErr = .T.
  2038.             
  2039.             RETURN
  2040.         ENDIF
  2041.         
  2042.         ConverterBase::Error(errorNum, method, line)
  2043.         
  2044.     ENDPROC
  2045. #endif
  2046.  
  2047.     *----------------------------------
  2048.     PROCEDURE CompileAllFrx            && PJXConverterBase
  2049.     *----------------------------------
  2050.         *- compile the FRX files in the converted project (save till end)
  2051.         LOCAL cFile
  2052.  
  2053.         SELECT (THIS.new30alias)
  2054.         SCAN FOR type $ C_REPORT + C_LABEL
  2055.  
  2056.             IF FILE(THIS.cHomeDir + STRTRAN(name,C_NULL,""))
  2057.                 cFile = THIS.cHomeDir + STRTRAN(name,C_NULL,"")
  2058.                 *- make sure file is converted and openable (maybe user bailed from transporting)
  2059.                 IF Readable(m.cFile) AND THIS.IsDBF(m.cFile)
  2060.                     SELECT 0
  2061.                     USE (m.cFile) EXCLUSIVE
  2062.                     IF FCOUNT() = C_30FRXFLDS AND FIELD(75) = "USER"
  2063.                         *- okay -- it's a 3.0 file
  2064.                         LOCATE FOR INLIST(objtype, N_FRX_DATAENV, N_FRX_CURSOR) AND platform = THIS.platform
  2065.                         IF FOUND()
  2066.                             THIS.CompileFRX
  2067.                             THIS.WriteLog(SYS(2027,m.cFile),C_COMPILE_LOC)
  2068.                         ENDIF
  2069.                     ENDIF
  2070.                     USE
  2071.                     SELECT (THIS.new30alias)
  2072.                 ENDIF
  2073.             ENDIF
  2074.         ENDSCAN
  2075.  
  2076.     ENDPROC        && CompileAllFrx
  2077.  
  2078.     *----------------------------------
  2079.     PROCEDURE CompileAllDBC
  2080.     *----------------------------------
  2081.         *- compile the DBC files in the converted project (save till end)
  2082.         LOCAL cFile, lIs30File, lOpenShared, i, iCnt, cOldDataBase
  2083.         LOCAL ARRAY aDBC[1]
  2084.         
  2085.         THIS.WriteLog("","")
  2086.  
  2087.         cOldDataBase = SET("DATABASE")
  2088.         
  2089.         SELECT (THIS.new30alias)
  2090.         SCAN FOR type = C_DBCTYPE
  2091.  
  2092.             m.lIs30File = .F.
  2093.  
  2094.             IF FILE(THIS.cHomeDir + STRTRAN(name,C_NULL,""))
  2095.                 cFile = THIS.cHomeDir + STRTRAN(name,C_NULL,"")
  2096.                 *- make sure file is converted and openable (maybe user bailed from transporting)
  2097.                 IF Readable(m.cFile) AND THIS.IsDBF(m.cFile)
  2098.                     SELECT 0
  2099.                     USE (m.cFile) EXCLUSIVE
  2100.                     IF FCOUNT() = C_30DBCFLDS AND FIELD(4) == "OBJECTNAME"
  2101.                         *- okay -- it's a 3.0 DBC file
  2102.                         m.lIs30File = .T.
  2103.                     ENDIF
  2104.                     USE
  2105.                     SELECT (THIS.new30alias)
  2106.                 ENDIF
  2107.                 IF m.lIs30File
  2108.                     lOpenShared = .F.
  2109.                     THIS.WriteLog(SYS(2027,m.cFile),C_COMPILE_LOC)
  2110.                     IF DBUSED(m.cFile)
  2111.                         iCnt = ADATABASES(aDBC)
  2112.                         FOR i = 1 TO iCnt
  2113.                             IF SYS(2027,aDBC[i,2]) = SYS(2027,m.cFile)
  2114.                                 IF !ISEXCLUSIVE(JustStem(m.cFile))
  2115.                                     m.lOpenShared = .T.
  2116.                                     SET DATABASE TO (aDBC[i,1])
  2117.                                     CLOSE DATABASE
  2118.                                     OPEN DATABASE (SYS(2027,m.cFile)) EXCLUSIVE
  2119.                                 ENDIF
  2120.                                 EXIT
  2121.                             ENDIF
  2122.                         NEXT
  2123.                     ENDIF
  2124.                     COMPILE DATABASE (m.cFile)
  2125.                     IF m.lOpenShared
  2126.                         CLOSE DATABASE
  2127.                         OPEN DATABASE (SYS(2027,m.cFile)) SHARED
  2128.                     ENDIF
  2129.                 ENDIF
  2130.             ENDIF
  2131.         ENDSCAN
  2132.  
  2133.         SET DATABASE TO &cOldDataBase
  2134.         
  2135.     ENDPROC        && CompileAllDBC
  2136.  
  2137.  
  2138.     *----------------------------------
  2139.     PROCEDURE Destroy
  2140.     *----------------------------------
  2141.     ENDPROC
  2142.  
  2143. ENDDEFINE    && PJXConverterBase 
  2144.  
  2145.  
  2146. **********************************************
  2147. DEFINE CLASS PJXConverter AS PJXConverterBase
  2148. **********************************************
  2149.  
  2150.     platform = ""
  2151.     winobj = ""
  2152.     DIMENSION aMasterParms[1]
  2153.     DIMENSION a_s2files[1,3]
  2154.     DIMENSION a_s3files[1]
  2155.     DIMENSION a_scx[1]            && array of unique screens in this project
  2156.     lSet30Defaults = .F.        && if converting a 3.0 project, may need to set 3.0 defaults
  2157.  
  2158.  
  2159.     *------------------
  2160.     PROCEDURE Init    && PJXConverter
  2161.     *------------------
  2162.         PARAMETER aParms
  2163.         
  2164.         *- temp until array stuff fixed
  2165.         PRIVATE tmparr
  2166.         LOCAL m.cold, m.i, m.j, m.nlen, m.nct, m.cTmpPjxName,m.setid
  2167.  
  2168.         m.setid = 0 && in case PJX 3.0
  2169.  
  2170.         gOPJX = THIS
  2171.  
  2172.         SET ESCAPE ON
  2173.         ON ESCAPE DO EscHandler
  2174.  
  2175.         =ACOPY(aParms,THIS.aMasterParms)
  2176.  
  2177.         THIS.nTimeStamp    = THIS.TStamp()
  2178.         THIS.pjxName    = aParms[4]
  2179.         THIS.cBackDir    = aParms[1]
  2180.         THIS.lDevMode    = aParms[7]
  2181.         THIS.cCodeFile    = aParms[8]
  2182.         THIS.lLog        = aParms[9]
  2183.         THIS.cLogFile    = aParms[10]
  2184.         THIS.lBackup    = aParms[11]
  2185.         THIS.iPlatformCount    = aParms[12]
  2186.  
  2187.         THIS.cCurrentFile = THIS.pjxName
  2188.         THIS.cMemoExt = "PJT"
  2189.  
  2190.         IF THIS.lLog
  2191.             THIS.WriteLog(C_CONVLOG_LOC + THIS.cCurrentFile + " [" + TTOC(DATETIME()) + "]","")
  2192.             THIS.WriteLog(C_CONVVERS_LOC + C_CONVERSION_LOC,"")
  2193.             THIS.WriteLog("","")
  2194.         ENDIF
  2195.  
  2196.         *- make a working copy of the PJX file, in case of transporting, so if
  2197.         *- user cancels, original will still be available
  2198.         cTmpPjxName = ADDBS(JUSTPATH(THIS.pjxName)) + 'P' + LEFT(SYS(3),7) + ".PJX"
  2199.         COPY FILE (THIS.pjxName) TO (m.cTmpPjxName)
  2200.         IF FILE(FORCEEXT(THIS.pjxName,"PJT"))
  2201.             COPY FILE (FORCEEXT(THIS.pjxName,"PJT")) TO (FORCEEXT(m.cTmpPjxName,"PJT"))
  2202.         ENDIF
  2203.         THIS.pjxName = m.cTmpPjxName
  2204.  
  2205.         *- project PJX file
  2206.         THIS.pjx25Alias = THIS.OpenFile(THIS.pjxName)
  2207.         IF EMPTY(THIS.pjx25Alias)
  2208.             THIS.lHadError = .T.
  2209.             RETURN .F.
  2210.         ENDIF
  2211.  
  2212.         gOTherm.visible = .T.
  2213.  
  2214.         *- Check for proper file format
  2215.         DO CASE
  2216.             CASE FCOUNT() = C_PJX40FLDS AND FIELD(1) = "NAME"        
  2217.                 *- legal VFP4 PJX 
  2218.             CASE FCOUNT() = C_PJX30FLDS AND FIELD(1) = "NAME"
  2219.                 *- legal VFP3 PJX
  2220.                 THIS.lSet30Defaults = (THIS.iPlatformCount > 1)
  2221.                 THIS.iPlatformCount = 1
  2222.             CASE FCOUNT() = C_PJX25FLDS AND FIELD(1) = "NAME"
  2223.                 *- check for 2.5 PJX type
  2224.             CASE FCOUNT() = c_pjx20flds AND FIELD(1) = "NAME"
  2225.                 *- check for 2.0 PJX type - if so, call transporter first.
  2226.                 USE IN (THIS.pjx25Alias)
  2227.                 *-=MESSAGEBOX(E_HAS20FILE_LOC)
  2228.                 IF !THIS.Conv20PJX()
  2229.                     THIS.lHadError = .T.
  2230.                     RETURN
  2231.                 ENDIF
  2232.             OTHERWISE
  2233.                 USE IN (THIS.pjx25Alias)
  2234.                 THIS.lHadError=.T.
  2235.                 =MESSAGEBOX(E_INVALPJX_LOC)
  2236.                 RETURN
  2237.         ENDCASE
  2238.         
  2239.  
  2240.         THIS.cBackDir = AddBS(THIS.cBackDir)
  2241.  
  2242.         LOCATE FOR Type = "H"
  2243.         
  2244.         THIS.lDebug = debug
  2245.         THIS.lEncrypt = encrypt
  2246.         THIS.cDevInfo = devinfo
  2247.         THIS.highscxid = setid
  2248.         THIS.cHomeDir = ADDBS(JUSTPATH(THIS.pjxName))
  2249.  
  2250.         COUNT FOR type = 'S' AND !DELETED() TO THIS.nScreenSets
  2251.         THIS.nScreenCtr = 1
  2252.  
  2253.         THIS.BackFiles("name", "s|R|B|V|K", C_CONVERT3p_LOC)    && backup screen, report and label files to back dir
  2254.  
  2255.         IF gOMaster.lHadError OR THIS.lHadError
  2256.             THIS.Cleanup
  2257.             THIS.lHadError = .T.
  2258.             RETURN .F.
  2259.         ENDIF
  2260.  
  2261.         *- this cursor is for working with SPR code if devmode
  2262.         IF USED("_FOX3PJX")
  2263.             USE IN _FOX3PJX
  2264.         ENDIF
  2265.  
  2266.         CREATE CURSOR _FOX3PJX (sprmemo m)
  2267.         APPEND BLANK
  2268.  
  2269.         gOTherm.Update2((1 - N_THERM2X) * 100,C_PROJTASK1_LOC)        && update therm with next task
  2270.         
  2271.     ENDPROC    && PJXConverter:Init
  2272.  
  2273.     *------------------------------------
  2274.     PROCEDURE Cleanup        && PJXConverter
  2275.     *------------------------------------
  2276.         *- this proc is called by Error, and tries to put things back the way they were
  2277.         *- copy files in backdir to original location
  2278.  
  2279.         LOCAL i, cPJXname, cBackName, cTmpFname, cExt, nTables, cOldExact
  2280.         PRIVATE af, au
  2281.  
  2282.         cOldExact = SET("EXACT")
  2283.         SET EXACT OFF            && for ASCAN
  2284.  
  2285.         IF WEXIST("transdlg")    && just in case (jd 03/23/96)
  2286.             RELEASE WINDOW transdlg
  2287.         ENDIF
  2288.  
  2289.         m.cPJXname = ""
  2290.  
  2291.         IF USED(THIS.pjx25Alias)
  2292.             SELECT UPPER(name), type FROM DBF(THIS.pjx25Alias) ;
  2293.                 WHERE type $ C_SCREENSET + C_REPORT + C_LABEL AND !DELETED() ;
  2294.                 INTO ARRAY tmparr
  2295.  
  2296.             IF USED(THIS.new30alias)
  2297.                 m.cPJXname = FULLPATH(DBF(THIS.new30alias),THIS.cHomeDir)
  2298.             ENDIF
  2299.  
  2300.         ELSE
  2301.             _TALLY = 0
  2302.         ENDIF
  2303.  
  2304.         *- force deletion of any lingering temp screen or report files
  2305.         IF _TALLY > 0
  2306.             m.nTables = AUSED(au)
  2307.             FOR i = 1 TO m.nTables
  2308.                 IF LEFT(au[i,1],1) = "S" OR LEFT(au[i,1],1) = "F"
  2309.                     cTmpFname = DBF(au[i,1])
  2310.                     cExt = UPPER(JustExt(cTmpFname))
  2311.                     IF ASCAN(tmparr,UPPER(JustFName(cTmpFName))) > 0
  2312.                         *- oops -- it;s one of the real ones
  2313.                         LOOP
  2314.                     ENDIF
  2315.                     IF INLIST(cExt,C_SCXEXT,"FRX","LBX")
  2316.                         USE IN (au[i,1])
  2317.                         ERASE (cTmpFname)
  2318.                         ERASE FORCEEXT(cTmpFname,IIF(m.cExt = C_SCXEXT,C_SCTEXT,;
  2319.                             IIF(m.cExt = "FRX","FRT","LBT")))
  2320.                     ENDIF
  2321.                 ENDIF
  2322.             NEXT
  2323.         ENDIF
  2324.         
  2325.         CLOSE TABLES
  2326.  
  2327.         IF THIS.lBackUp
  2328.             FOR i = 1 TO _TALLY
  2329.                 *- Copy files from backup directory
  2330.                 m.cTmpFname = FULLPATH(ALLTRIM(IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  2331.                     LEFT(tmparr[m.i,1],AT(CHR(0),tmparr[m.i,1])-1),tmparr[m.i,1])),THIS.cHomeDir)
  2332.                 m.cBackName = THIS.cBackDir + JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL))
  2333.                 IF FILE(m.cBackName)   && is file there?
  2334.                     IF FILE(m.cTmpFname)
  2335.                         *- old file is there
  2336.                         *- try to get rid of it
  2337.                         DELETE FILE (m.cTmpFname)
  2338.                         IF FILE(m.cTmpFname)
  2339.                             *- still there -- maybe it is read-only, so skip
  2340.                             LOOP
  2341.                         ENDIF
  2342.                     ENDIF
  2343.                     COPY FILE (m.cBackName) TO (m.cTmpFname)
  2344.                     DO CASE
  2345.                         CASE tmparr[m.i,2] = 's' OR tmparr[m.i,2] = 'scx'
  2346.                             *- assume screen/form
  2347.                             IF FILE(FORCEEXT(m.cBackName,C_SCTEXT))
  2348.                                 COPY FILE (FORCEEXT(m.cBackName,C_SCTEXT)) TO (FORCEEXT(m.cTmpFname,C_SCTEXT))
  2349.                             ENDIF
  2350.                         CASE tmparr[m.i,2] = 'R' OR tmparr[m.i,2] = 'frx'
  2351.                             *- assume report form
  2352.                             IF FILE(FORCEEXT(m.cBackName,"FRT"))
  2353.                                 COPY FILE (FORCEEXT(m.cBackName,"FRT")) TO (FORCEEXT(m.cTmpFname,"FRT"))
  2354.                             ENDIF
  2355.                         CASE tmparr[m.i,2] $ 'B' OR tmparr[m.i,2] = 'lbx'
  2356.                             *- assume label
  2357.                             IF FILE(FORCEEXT(m.cBackName,"LBT"))
  2358.                                 COPY FILE (FORCEEXT(m.cBackName,"LBT")) TO (FORCEEXT(m.cTmpFname,"LBT"))
  2359.                             ENDIF
  2360.                     ENDCASE
  2361.                 ENDIF
  2362.             NEXT
  2363.  
  2364.             *-now, erase files in backup dir
  2365.             =ADIR(af,THIS.cBackDir + "*.*")
  2366.             IF TYPE("af") # 'U'
  2367.                 FOR i = 1 TO ALEN(af,1)
  2368.                     IF af[i,5] $ 'RD'
  2369.                         LOOP
  2370.                     ENDIF
  2371.                     DELETE FILE (THIS.cBackDir + af[i,1])
  2372.                 NEXT
  2373.                 RELEASE af
  2374.             ENDIF
  2375.             IF ADIR(af,THIS.cBackDir + "*.*") = 0
  2376.                 IF TYPE("af") = 'U'
  2377.                     RD (THIS.cBackDir)
  2378.                 ENDIF
  2379.             ENDIF
  2380.         ENDIF && THIS.lBackUp
  2381.  
  2382.         *- erase temp files
  2383.         IF FILE(m.cPJXname)
  2384.             DELETE FILE (m.cPJXname)
  2385.         ENDIF
  2386.         IF FILE(FORCEEXT(m.cPJXname,"PJT"))
  2387.             DELETE FILE (FORCEEXT(m.cPJXname,"PJT"))
  2388.         ENDIF
  2389.  
  2390.         IF FILE(THIS.PJXname)
  2391.             DELETE FILE (THIS.PJXname)
  2392.         ENDIF
  2393.         IF FILE(FORCEEXT(THIS.PJXname,"PJT"))
  2394.             DELETE FILE (FORCEEXT(THIS.PJXname,"PJT"))
  2395.         ENDIF
  2396.  
  2397.         SET EXACT &cOldExact
  2398.  
  2399.     ENDPROC    && PJXConverter:Cleanup
  2400.  
  2401.     *----------------------------------
  2402.     PROCEDURE Converter        && PJXConverter
  2403.     *----------------------------------
  2404.         *- convert PJX itself
  2405.         *- convert each of the objects in it
  2406.  
  2407.         PRIVATE i, z, oForm, cSaveArea
  2408.         LOCAL cOld, iWhichPlat, cExt1, cExt2
  2409.         DIMENSION aPlatforms[1]
  2410.  
  2411.         cOld = THIS.pjx25Alias
  2412.         SELECT (m.cOld)
  2413.  
  2414.         *- Get record count for thermometer
  2415.         THIS.nRecCount = RECC()
  2416.         THIS.nTmpCount = 1      && reset
  2417.  
  2418.         *- External preprocessor hook
  2419.           THIS.PreForm
  2420.  
  2421.         *- Create new PJX file here
  2422.         THIS.CreatePJX
  2423.  
  2424.         *- Add records from old PJX file
  2425.         SELECT (THIS.pjx25Alias)
  2426.  
  2427.         *- next, do all the screens
  2428.         FOR m.z = 1 TO THIS.highscxid    && will be 0 for 3.0
  2429.         
  2430.             *- Get screen set array to process screen sets
  2431.             THIS.lIsMain = .F.
  2432.             THIS.GetNextFset(m.z)
  2433.             
  2434.             *- Check to see if screen missing from project such as 
  2435.             *- when it is deleted since FoxPro uses next highest number.
  2436.             IF EMPTY(THIS.cOutFile)
  2437.                 LOOP
  2438.             ENDIF
  2439.  
  2440.             *- Call preprocessor external hook
  2441.             THIS.extproj
  2442.  
  2443.             aParms[12] = 1
  2444.  
  2445.             IF THIS.iPlatformCount > 1
  2446.                 *- convert multiple platforms in present
  2447.                 *- if multiple platforms, cycle through for each platform
  2448.                 DIMENSION aPlatforms[1]
  2449.                 aPlatforms[1] = ""
  2450.                 THIS.GetPlatformCount(THIS.a_s3files[1], @aPlatforms)
  2451.                 IF EMPTY(aPlatforms[1])
  2452.                     *- was unable to determine platforms
  2453.                     LOOP
  2454.                 ENDIF
  2455.                 IF ALEN(aPlatforms,1) > 1
  2456.                     IF ASCAN(aPlatforms,C_WINDOWS) > 0 AND ASCAN(aPlatforms,C_MAC) > 0
  2457.                         *- both platforms are there
  2458.                         aParms[12] = 2
  2459.                     ENDIF
  2460.                 ENDIF
  2461.             ELSE
  2462.                 aPlatforms[1] = THIS.GetPlatForm()
  2463.             ENDIF
  2464.  
  2465.             FOR m.iWhichPlat = 1 TO aParms[12]
  2466.  
  2467.                 *- Initialize form set object
  2468.                 aParms[13] = m.iWhichPlat
  2469.                 oForm = CREATEOBJ(THIS.scxConverterClass, @aParms, .F., .T.,.T.,.T.)    && no backup, 
  2470.                                                                                         && is a project, 
  2471.                                                                                         && show ext transpo dlog
  2472.                                                                                         && don;t compile (we do that all at once at the end)
  2473.  
  2474.                 IF TYPE("oForm") # "O"
  2475.                     *- object wasn't created (?)
  2476.                     THIS.lHadError = .T.
  2477.                 ELSE
  2478.                     IF oForm.lHadError
  2479.                         THIS.lHadError = .T.
  2480.                         *- try and close the file (jd 02/13/96)
  2481.                         IF USED(oForm.c25alias)
  2482.                             USE IN (oForm.c25alias)
  2483.                         ENDIF
  2484.                         RELEASE oForm            && dispose of object
  2485.                     ENDIF
  2486.                 ENDIF
  2487.                 
  2488.  
  2489.                 IF !THIS.lHadError
  2490.                     IF !oForm.lConverted
  2491.                         *- only convert the unconverted
  2492.                         oForm.Converter
  2493.                     ELSE
  2494.                         *- still need to know .SPR file location though
  2495.                         SELECT (THIS.pjx25Alias)
  2496.                         LOCATE FOR setid = m.z AND type = "S"
  2497.                         IF FOUND()
  2498.                             *- create an SPR file from the stored SPR code
  2499.                             THIS.cStubFile = FULLPATH(ALLTRIM(SUBSTR(outfile,1,AT(C_NULL,outfile)-1)),THIS.cHomeDir)
  2500.  
  2501.                             *- make sure this is a valid path
  2502.                             IF !IsDir(JUSTPATH(THIS.cStubFile))
  2503.                                 *- invalid path, so try and make a good one
  2504.                                 THIS.cStubFile = AddBS(THIS.cHomeDir) + JUSTFNAME(THIS.cStubFile)
  2505.                             ENDIF
  2506.  
  2507.                             SELECT (oForm.c25alias)
  2508.                             GO TOP
  2509.                             IF !EMPTY(user)
  2510.                                 COPY MEMO user TO (THIS.cStubFile)
  2511.                             ENDIF
  2512.                             THIS.WriteLog(THIS.cOutFile,C_FILECONV_LOC + C_CREATMSG_LOC)
  2513.                             IF USED(oForm.c25alias)
  2514.                                 USE IN (oForm.c25alias)
  2515.                             ENDIF
  2516.                         ELSE
  2517.                             *- error            
  2518.                             *- try and close the file (jd 02/13/96)
  2519.                             IF USED(oForm.c25alias)
  2520.                                 USE IN (oForm.c25alias)
  2521.                             ENDIF
  2522.                             THIS.lHadError = .T.
  2523.                             RELEASE oForm            && dispose of object
  2524.                             LOOP                    && continue converting
  2525.                         ENDIF
  2526.                     ENDIF
  2527.                 ELSE
  2528.                     *- reset this flag
  2529.                     THIS.lHadError = .F.
  2530.                 ENDIF && THIS.lHadError
  2531.  
  2532.             NEXT        && going through each platform
  2533.  
  2534.             *- get rid of temp files we created
  2535.             FOR m.i = 1 TO ALEN(THIS.a_s2files,1)
  2536.                 IF FILE(THIS.a_s2files[i,1])
  2537.                     DELETE FILE (THIS.a_s2files[i,1])
  2538.                 ENDIF
  2539.                 IF FILE(FORCEEXT((THIS.a_s2files[i,1]),C_SCTEXT))
  2540.                     DELETE FILE (FORCEEXT((THIS.a_s2files[i,1]),C_SCTEXT))
  2541.                 ENDIF
  2542.             NEXT
  2543.  
  2544.             *- add records to PJX file, even if not converted
  2545.             THIS.InsertSCX
  2546.  
  2547.             THIS.nScreenCtr = THIS.nScreenCtr + 1
  2548.  
  2549.         ENDFOR    && end of screen set loop
  2550.  
  2551.         gOTherm.Update2(N_THERM3X * 100,C_PROJTASK2_LOC)    && update project therm
  2552.  
  2553.         *- move other files to new project
  2554.         SELECT (THIS.pjx25Alias)
  2555.         SCAN FOR !DELETED()
  2556.             DO CASE
  2557.                 CASE type = C_SCREENSET
  2558.                     *- already handled above
  2559.                     LOOP
  2560.                 CASE type = C_SCREEN
  2561.                     *- already handled above
  2562.                     LOOP
  2563.                 CASE type = C_HEADER
  2564.                     *- already handled above
  2565.                     LOOP
  2566.                 CASE type $ C_VCXTYPE + C_SCXTYPE
  2567.                     *- we may need to set the 30 properties
  2568.                     IF THIS.lSet30Defaults
  2569.                         *- setup arrays with file names
  2570.                         *- dimension 1 = name of actual file that will be converted
  2571.                         *-           2 = arranged
  2572.                         *-           3 = original name of screen
  2573.  
  2574.                         DIMENSION THIS.a_s2files[1,3]
  2575.                         DIMENSION THIS.a_s3files[1]
  2576.  
  2577.                         THIS.a_s3files[1] = FULLPATH(ALLTRIM(;
  2578.                             IIF(AT(CHR(0),name) > 0,;
  2579.                                 SUBSTR(name,1,AT(CHR(0),name)-1),;
  2580.                                 name)),;
  2581.                             THIS.cHomeDir)
  2582.                         THIS.a_s2files[1,3] = JUSTFNAME(STRTRAN(name,C_NULL))
  2583.                         cext1 = JustExt(THIS.a_s2files[1,3])
  2584.                         cext2 = IIF(cext1 == C_VCXEXT, C_VCTEXT, C_SCTEXT)
  2585.                         THIS.a_s2files[1,1] = "S" + RIGHT(SYS(3),7) + '.' + m.cext1
  2586.                         IF THIS.lBackup
  2587.                             *- make sure the files are there
  2588.                             IF FILE(THIS.cBackDir + THIS.a_s2files[1,3]) AND FILE(FORCEEXT(THIS.cBackDir + THIS.a_s2files[1,3],m.cext2))
  2589.                                 COPY FILE (THIS.cBackDir + THIS.a_s2files[1,3]) TO (THIS.a_s2files[1,1])
  2590.                                 COPY FILE (FORCEEXT(THIS.cBackDir + THIS.a_s2files[1,3],m.cext2)) TO ;
  2591.                                     (FORCEEXT(THIS.a_s2files[1,1],m.cext2))
  2592.                             ELSE
  2593.                                 *- file not found
  2594.                                 THIS.WriteLog(E_FILE_LOC + THIS.a_s2files[1,3] + E_NOCONVERT1_LOC,"")
  2595.                                 THIS.cOutFile = ""
  2596.                                 LOOP
  2597.                             ENDIF
  2598.                         ELSE
  2599.                             IF !FILE(THIS.a_s3files[1]) OR !FILE(FORCEEXT(THIS.a_s3files[1],m.cext2))
  2600.                                 *- file not found
  2601.                                 THIS.WriteLog(E_FILE_LOC + THIS.a_s3files[1] + E_NOCONVERT1_LOC,"")
  2602.                                 THIS.cOutFile = ""
  2603.                                 LOOP
  2604.                             ENDIF
  2605.                             COPY FILE (THIS.a_s3files[1]) TO (THIS.a_s2files[1,1])
  2606.                             COPY FILE (FORCEEXT(THIS.a_s3files[1],m.cext2)) TO ;
  2607.                                 (FORCEEXT(THIS.a_s2files[1,1],m.cext2))
  2608.                         ENDIF
  2609.  
  2610.                         *- we set the 30 default values in the INIT, so throw object away when done
  2611.                         oForm = CREATEOBJ(THIS.scx30ConverterClass, @aParms, .F., .T.,.T.,.T.)    && no backup, 
  2612.                                                                                                 && is a project, 
  2613.                                                                                                 && show ext transpo dlog
  2614.                                                                                                 && don;t compile (we do that all at once at the end)
  2615.  
  2616.                         IF TYPE("oForm") # "O"
  2617.                             *- object wasn't created (?)
  2618.                             THIS.lHadError = .T.
  2619.                         ELSE
  2620.                             IF oForm.lHadError
  2621.                                 THIS.lHadError = .T.
  2622.                                 *- try and close the file
  2623.                                 IF USED(oForm.c25alias)
  2624.                                     USE IN (oForm.c25alias)
  2625.                                 ENDIF
  2626.                             ENDIF
  2627.  
  2628.                             oForm.Converter
  2629.  
  2630.                             oForm.oConvForm = .NULL.
  2631.  
  2632.                             RELEASE oForm            && dispose of object
  2633.                         ENDIF
  2634.  
  2635.                         
  2636.                         *- get rid of temp files we created
  2637.                         IF FILE(THIS.a_s2files[1,1])
  2638.                             COPY FILE (THIS.a_s2files[1,1]) TO (THIS.a_s3files[1])
  2639.                             DELETE FILE (THIS.a_s2files[1,1])
  2640.                         ENDIF
  2641.                         IF FILE(FORCEEXT((THIS.a_s2files[1,1]),m.cext2))
  2642.                             COPY FILE (FORCEEXT(THIS.a_s2files[1,1],m.cext2)) TO ;
  2643.                                 (FORCEEXT(THIS.a_s3files[1],m.cext2))
  2644.                             DELETE FILE (FORCEEXT((THIS.a_s2files[1,1]),m.cext2))
  2645.                         ENDIF
  2646.  
  2647.             
  2648.                     ENDIF
  2649.  
  2650.                     THIS.cOutFile = STRTRAN(EVAL(cOld + '.name'),C_NULL)
  2651.                     INSERT INTO (THIS.new30alias) ;
  2652.                         (name,mainprog,type,timestamp,homedir,exclude,key);
  2653.                         VALUES(EVAL(cOld + '.name'),;
  2654.                             EVAL(cOld + '.mainprog'),;
  2655.                             EVAL(cOld + '.type'),;
  2656.                             EVAL(cOld + '.timestamp'),;
  2657.                             EVAL(cOld + '.homedir'),;
  2658.                             EVAL(cOld + '.exclude'),;
  2659.                             UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  2660.                     THIS.p30to40
  2661.  
  2662.                 CASE type = C_REPORT OR type = C_LABEL
  2663.                     LOCAL m.cfrxext, m.cfrtext
  2664.                     m.cfrxext = IIF(type = C_REPORT,"FRX","LBX")
  2665.                     m.cfrtext = IIF(type = C_REPORT,"FRT","LBT")
  2666.                     *- Initialize report object
  2667.                     THIS.f2files = "F" + RIGHT(SYS(3),7) + '.' + m.cfrxext
  2668.                     THIS.f3files = FULLPATH(ALLTRIM(;
  2669.                         IIF(AT(CHR(0),name) > 0,;
  2670.                             SUBSTR(name,1,AT(CHR(0),name)-1),;
  2671.                             name)),;
  2672.                         THIS.cHomeDir)
  2673.                     IF !FILE(IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files)) OR ;
  2674.                         !FILE(FORCEEXT(IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files),m.cfrtext))
  2675.                         *- file not found
  2676.                         THIS.WriteLog(E_FILE_LOC + THIS.f3files + E_NOCONVERT1_LOC,"")
  2677.                         LOOP
  2678.                     ENDIF
  2679.                     COPY FILE (IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files)) TO (THIS.f2files)
  2680.                     COPY FILE (FORCEEXT(IIF(THIS.lBackUp,THIS.cBackDir + JUSTFNAME(THIS.f3files),THIS.f3files),m.cfrtext)) TO ;
  2681.                         (FORCEEXT(THIS.f2files,m.cfrtext))
  2682.                     oForm = CREATEOBJ(THIS.frxConverterClass, @aParms, .F., .T., .T., .T.)
  2683.  
  2684.                     IF TYPE("oForm") # "O"
  2685.                         *- object wasn't created (?)
  2686.                         THIS.lHadError = .T.
  2687.                     ENDIF
  2688.  
  2689.                     IF !THIS.lHadError
  2690.                         IF !oForm.lHadError
  2691.                             IF !oForm.lConverted
  2692.                                 *- only convert the unconverted
  2693.                                 oForm.Converter
  2694.                             ELSE
  2695.                                 THIS.WriteLog(THIS.f3files,C_FILECONV_LOC + '.' + C_CRLF)
  2696.                                 IF USED(oForm.c25alias)
  2697.                                     USE IN (oForm.c25alias)
  2698.                                 ENDIF
  2699.                             ENDIF
  2700.                         ENDIF
  2701.                     ELSE
  2702.                         *- reset this flag
  2703.                         THIS.lHadError = .F.
  2704.                     ENDIF
  2705.  
  2706.                     *- erase temp files
  2707.                     IF FILE(THIS.f2files)
  2708.                         DELETE FILE (THIS.f2files)
  2709.                     ENDIF
  2710.                     IF FILE (FORCEEXT(THIS.f2files,m.cfrtext))
  2711.                         DELETE FILE (FORCEEXT(THIS.f2files,m.cfrtext))
  2712.                     ENDIF
  2713.  
  2714.                     INSERT INTO (THIS.new30alias) ;
  2715.                         (name,mainprog,type,timestamp,homedir,exclude,key);
  2716.                         VALUES(EVAL(cOld + '.name'),;
  2717.                             EVAL(cOld + '.mainprog'),;
  2718.                             EVAL(cOld + '.type'),;
  2719.                             EVAL(cOld + '.timestamp'),;
  2720.                             EVAL(cOld + '.homedir'),;
  2721.                             EVAL(cOld + '.exclude'),;
  2722.                             UPPER(LEFT(JUSTSTEM(THIS.f3files),LEN(key))))
  2723.                     THIS.p30to40
  2724.                     
  2725.                 CASE type = C_PRGTYPE
  2726.                     *- program -- check to make sure it isn;t a duplicate 
  2727.                     *- of an SPR already in the file
  2728.                     cSaveArea = SELECT()
  2729.                     THIS.cOutFile = STRTRAN(EVAL(cOld + '.name'),C_NULL)
  2730.                     SELECT (THIS.new30alias)
  2731.                     LOCATE FOR UPPER(JUSTFNAME(THIS.cOutFile)) $ UPPER(name)
  2732.                     IF FOUND()
  2733.                         *- .SPR file is already there, or it is a duplicate
  2734.                         *- log and continue
  2735.                         THIS.WriteLog(THIS.cOutFile,C_FILEFOUNDMSG_LOC)
  2736.                     ELSE
  2737.                         INSERT INTO (THIS.new30alias) ;
  2738.                             (name,mainprog,type,timestamp,homedir,exclude,key);
  2739.                             VALUES(EVAL(cOld + '.name'),;
  2740.                                 EVAL(cOld + '.mainprog'),;
  2741.                                 EVAL(cOld + '.type'),;
  2742.                                 EVAL(cOld + '.timestamp'),;
  2743.                                 EVAL(cOld + '.homedir'),;
  2744.                                 EVAL(cOld + '.exclude'),;
  2745.                                 UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  2746.                         THIS.p30to40
  2747.                         THIS.WriteLog(THIS.cOutFile,C_NOCONVMSG_LOC)
  2748.                     ENDIF
  2749.                     SELECT (m.cSaveArea)
  2750.                 OTHERWISE
  2751.                     THIS.cOutFile = STRTRAN(EVAL(cOld + '.name'),C_NULL)
  2752.                     INSERT INTO (THIS.new30alias) ;
  2753.                         (name,mainprog,type,timestamp,homedir,exclude,key);
  2754.                         VALUES(EVAL(cOld + '.name'),;
  2755.                             EVAL(cOld + '.mainprog'),;
  2756.                             EVAL(cOld + '.type'),;
  2757.                             EVAL(cOld + '.timestamp'),;
  2758.                             EVAL(cOld + '.homedir'),;
  2759.                             EVAL(cOld + '.exclude'),;
  2760.                             UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  2761.                     THIS.p30to40
  2762.                     THIS.WriteLog(THIS.cOutFile,C_NOCONVMSG_LOC)
  2763.             ENDCASE
  2764.         ENDSCAN
  2765.  
  2766.         SELECT (THIS.new30Alias)
  2767.         REPLACE TIMESTAMP WITH this.tstamp() + RECNO() ,;
  2768.             ID WITH timestamp FOR TYPE != 'H'
  2769.  
  2770.         *- compile the SCX files
  2771.         THIS.CompileAllScx
  2772.  
  2773.         *- compile the FRX files
  2774.         THIS.CompileAllFRX
  2775.  
  2776.         *- compile the DBC files
  2777.         THIS.CompileAllDBC
  2778.  
  2779.         *- Close project
  2780.         THIS.ClosePJX
  2781.  
  2782.         *- close up gOTherm
  2783.         gOTherm.Complete2
  2784.  
  2785.         gOPJX = .NULL.
  2786.  
  2787.         RETURN THIS.cCurrentFile
  2788.  
  2789.     ENDPROC    && PJXConverter:Converter
  2790.  
  2791.     *------------------
  2792.     PROCEDURE p30to40
  2793.     *------------------
  2794.     *- if it's a 30 pjx, copy USER and COMMENTS fields
  2795.         SELECT (this.new30Alias)
  2796.         IF TYPE(this.pjx25Alias+".Comments") # 'U'
  2797.             REPLACE Comments WITH ;
  2798.                 (EVAL(this.pjx25Alias+".Comments"))
  2799.         ENDIF
  2800.         IF TYPE(this.pjx25Alias+".User") # 'U'
  2801.             REPLACE User WITH ;
  2802.                 (EVAL(this.pjx25Alias+".User"))
  2803.         ENDIF
  2804.     ENDPROC
  2805.     
  2806.     *------------------
  2807.     PROCEDURE ExtProj
  2808.     *------------------
  2809.     *- this is an external hook to preprocess
  2810.     *- project object via subclassing
  2811.     ENDPROC
  2812.  
  2813.     *----------------------------------
  2814.     PROCEDURE InsertSCX            && PJXConverter
  2815.     *----------------------------------
  2816.         *- add appropriate record(s) to 3.0 PJX file
  2817.         PARAMETER lNoAddSPR
  2818.  
  2819.         LOCAL cFileName
  2820.  
  2821.         cFileName = SYS(2014,THIS.cOutFile,DBF(THIS.new30alias))
  2822.  
  2823.         INSERT INTO (THIS.new30alias) ;
  2824.             (name,timestamp,type,exclude,key);
  2825.             VALUES(;
  2826.                 cFileName + CHR(0),;
  2827.                 THIS.nTimeStamp,;
  2828.                 C_SCXTYPE,;
  2829.                 THIS.lExclude,;
  2830.                 UPPER(LEFT(JustFName(THIS.cOutFile),LEN(key))))
  2831.  
  2832.         IF THIS.iPlatformCount > 1 AND aParms[12] > 1
  2833.             *- converting more than one platform (i.e., also Mac) so add Mac form record
  2834.             m.cFileName = JustStem(cFileName) + C_MACEXT + "." + JustExt(cFileName)
  2835.             INSERT INTO (THIS.new30alias) ;
  2836.                 (name,timestamp,type,exclude,key);
  2837.                 VALUES(;
  2838.                     cFileName + CHR(0),;
  2839.                     THIS.nTimeStamp,;
  2840.                     C_SCXTYPE,;
  2841.                     THIS.lExclude,;
  2842.                     UPPER(LEFT(JustStem(THIS.cOutFile) + C_MACEXT + JustExt(THIS.cOutFile),LEN(key))))
  2843.         ENDIF
  2844.  
  2845.         IF !lNoAddSPR
  2846.             PJXConverterBase::InsertSCX
  2847.         ENDIF
  2848.  
  2849.     ENDPROC
  2850.  
  2851.     *------------------
  2852.     PROCEDURE Conv20PJX
  2853.     *------------------
  2854.         *- This converts a 2.0 project to a 2.5 one.
  2855.         *- transprt is built into this app
  2856.         LOCAL m.oldudfp
  2857.  
  2858.         gOTherm.SetTitle2(C_THERMMSG6_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  2859.         m.oldudfp = SET("UDFP")
  2860.         SET UDFP TO REFERENCE
  2861.         DO (gTransport) WITH THIS.pjxName,1,.F.,gAShowMe,m.gOTherm,THIS.cCurrentFile
  2862.         SET UDFP TO &oldudfp
  2863.         SET MESSAGE TO C_PROJTASK4_LOC
  2864.         gOTherm.SetTitle2(C_THERMMSG1_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  2865.         THIS.pjx25Alias = THIS.OpenFile(THIS.pjxName)
  2866.         IF FCOUNT() # C_PJX25FLDS OR FIELD(1) # "NAME"
  2867.             USE IN (THIS.pjx25Alias)
  2868.             THIS.lHadError = .T.
  2869.             RETURN .F.
  2870.         ENDIF
  2871.         RETURN .T.
  2872.     ENDPROC                && PJXConverter
  2873.  
  2874.     *------------------
  2875.     PROCEDURE ClosePJX    && PJXConverter
  2876.     *------------------
  2877.         m.cTmpFname = FULLPATH(THIS.cCurrentFile,THIS.cHomeDir)
  2878.         *m.cTmpFname = FULLPATH(DBF(THIS.pjx25Alias),THIS.cHomeDir)
  2879.         m.cBackName = IIF(!EMPTY(THIS.cBackDir),THIS.cBackDir,"") + JUSTFNAME(THIS.cCurrentFile)    && JUSTFNAME(DBF(THIS.pjx25Alias))
  2880.  
  2881.         IF USED("_FOX3PJX")
  2882.             IF THIS.lDevMode
  2883.                 COPY MEMO _FOX3PJX.sprmemo TO (THIS.cCodeFile)
  2884.                 *- add the devmode code file to the project
  2885.                 INSERT INTO (THIS.new30alias) ;
  2886.                     (name,mainprog,type,timestamp,homedir,exclude,key);
  2887.                     VALUES(THIS.cCodeFile,;
  2888.                         .F.,;
  2889.                         C_PRGTYPE,;
  2890.                         THIS.nTimeStamp,;
  2891.                         THIS.cHomeDir,;
  2892.                         .F.,;
  2893.                         UPPER(LEFT(JUSTSTEM(THIS.cCodeFile),LEN(key))))
  2894.             ENDIF
  2895.             USE IN _FOX3PJX
  2896.         ENDIF
  2897.  
  2898.         THIS.CloseFiles
  2899.  
  2900.         *- get rid of temp file
  2901.         IF FILE(THIS.pjxName)
  2902.             DELETE FILE (THIS.pjxName)
  2903.         ENDIF
  2904.         IF FILE(FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  2905.             DELETE FILE (FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  2906.         ENDIF
  2907.  
  2908.         *- Rename new FP3 project
  2909.         DELETE FILE (m.cTmpFname)
  2910.         DELETE FILE (FORCEEXT(m.cTmpFname,"PJT"))
  2911.  
  2912.         IF FILE(ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJX")
  2913.             RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJX") TO (m.cTmpFname)
  2914.         ENDIF
  2915.         IF FILE(ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJT")
  2916.             RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJT") TO (FORCEEXT(m.cTmpFname,"PJT"))
  2917.         ENDIF
  2918.  
  2919.     ENDPROC        &&   ClosePJX
  2920.  
  2921.     *---------------------
  2922.     PROCEDURE GetNextFset
  2923.     *---------------------
  2924.         PARAMETER pSetid
  2925.         PRIVATE tmparr,i 
  2926.         
  2927.         THIS.curscxid = m.pSetid    && get current screen ID number
  2928.                 
  2929.         *- Handle project PJX file
  2930.         SELECT (THIS.pjx25Alias)
  2931.         
  2932.         SELECT name,arranged,exclude FROM DBF(THIS.pjx25Alias) ;
  2933.             WHERE type = "s" AND setid = pSetid AND !DELETED() ;
  2934.             ORDER by scrnorder ;
  2935.             INTO ARRAY tmparr
  2936.  
  2937.         IF _TALLY = 0
  2938.             *- Screen is missing from set, so skip and go to next one.
  2939.             THIS.cOutFile = ""
  2940.             RETURN
  2941.         ENDIF
  2942.         
  2943.         *- setup arrays with file names
  2944.         *- dimension 1 = name of actual file that will be converted
  2945.         *-           2 = arranged
  2946.         *-           3 = original name of screen
  2947.         DIMENSION THIS.a_s2files[_TALLY,3]
  2948.         DIMENSION THIS.a_s3files[_TALLY]
  2949.  
  2950.         THIS.lExclude = tmparr[1,3]
  2951.  
  2952.         FOR i = 1 TO _TALLY
  2953.             THIS.a_s3files[m.i] = FULLPATH(ALLTRIM(;
  2954.                 IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  2955.                     SUBSTR(tmparr[m.i,1],1,AT(CHR(0),tmparr[m.i,1])-1),;
  2956.                     tmparr[m.i,1])),;
  2957.                 THIS.cHomeDir)
  2958.             THIS.a_s2files[m.i,1] = "S" + RIGHT(SYS(3),7) + ".SCX"
  2959.             THIS.a_s2files[m.i,3] = JUSTFNAME(STRTRAN(tmparr[m.i,1],C_NULL))
  2960.             IF THIS.lBackup
  2961.                 *- make sure the files are there
  2962.                 IF FILE(THIS.cBackDir + THIS.a_s2files[m.i,3]) AND FILE(FORCEEXT(THIS.cBackDir + THIS.a_s2files[m.i,3],C_SCTEXT))
  2963.                     COPY FILE (THIS.cBackDir + THIS.a_s2files[m.i,3]) TO (THIS.a_s2files[m.i,1])
  2964.                     COPY FILE (FORCEEXT(THIS.cBackDir + THIS.a_s2files[m.i,3],C_SCTEXT)) TO ;
  2965.                         (FORCEEXT(THIS.a_s2files[m.i,1],C_SCTEXT))
  2966.                 ELSE
  2967.                     *- Screen is missing, so skip
  2968.                     THIS.cOutFile = ""
  2969.                     RETURN
  2970.                 ENDIF
  2971.             ELSE
  2972.                 IF !FILE(THIS.a_s3files[m.i]) OR !FILE(FORCEEXT(THIS.a_s3files[m.i],C_SCTEXT))
  2973.                     *- file not found
  2974.                     THIS.WriteLog(E_FILE_LOC + THIS.a_s3files[m.i] + E_NOCONVERT1_LOC,"")
  2975.                     THIS.cOutFile = ""
  2976.                     RETURN
  2977.                 ENDIF
  2978.                 COPY FILE (THIS.a_s3files[m.i]) TO (THIS.a_s2files[m.i,1])
  2979.                 COPY FILE (FORCEEXT(THIS.a_s3files[m.i],C_SCTEXT)) TO ;
  2980.                     (FORCEEXT(THIS.a_s2files[m.i,1],C_SCTEXT))
  2981.             ENDIF
  2982.             THIS.a_s2files[m.i,2] = tmparr[m.i,2]
  2983.         ENDFOR
  2984.  
  2985.         *- Get output file SPR name and screen set settings
  2986.         LOCATE FOR setid = m.pSetid AND type = "S"
  2987.         IF FOUND()
  2988.             THIS.cStubFile = FULLPATH(ALLTRIM(SUBSTR(outfile,1,AT(C_NULL,outfile)-1)),THIS.cHomeDir)
  2989.             *- make sure this is a valid path
  2990.             IF !IsDir(JUSTPATH(THIS.cStubFile))
  2991.                 *- invalid path, so try and make a good one
  2992.                 THIS.cStubFile = AddBS(THIS.cHomeDir) + JUSTFNAME(THIS.cStubFile)
  2993.             ENDIF
  2994.         ELSE
  2995.             THIS.cOutFile = ""
  2996.             RETURN            
  2997.         ENDIF
  2998.  
  2999.         THIS.cOutFile = THIS.a_s3files[1,1]
  3000.  
  3001.         *- also, remember the main
  3002.         THIS.lIsMain = mainprog
  3003.             
  3004.         *- populate settings array with Project options
  3005.         THIS.a_pjxsets[A_OPENFILES]  = openFiles    && open DBF files
  3006.         THIS.a_pjxsets[A_CLOSEFILES] = closeFiles    && close DBF files
  3007.         THIS.a_pjxsets[A_DEFWINDOWS] = defwinds        && define windows
  3008.         THIS.a_pjxsets[A_RELWINDOWS] = relwinds        && release windows
  3009.         THIS.a_pjxsets[A_READMODAL]  = IIF(!EMPTY(assocwinds),.F.,modal)        && READ MODAL
  3010.         THIS.a_pjxsets[A_GETBORDERS] = nologo        && border for GETs
  3011.         THIS.a_pjxsets[A_READCYCLE]  = readcycle    && READ CYCLE
  3012.         THIS.a_pjxsets[A_READNOLOCK] = nolock        && READ NOLOCK
  3013.          THIS.a_pjxsets[A_MULTIREADS] = multreads    && multiple READs
  3014.          THIS.a_pjxsets[A_ASSOCWINDS] = assocwinds    && associated windows
  3015.  
  3016.         IF !THIS.a_pjxsets[9]  AND ALEN(THIS.a_s3files) > 1        && multireads
  3017.             DIMENSION THIS.a_s3files[1]
  3018.         ENDIF
  3019.  
  3020.         gOTherm.Update2((THIS.nScreenCtr/(THIS.nScreenSets + 1) * N_THERM2X + (1 - N_THERM2X)) * 100)    && (1) account for jump start we gave when backing up
  3021.                 
  3022.     ENDPROC        &&   GetNextFset
  3023.  
  3024. ENDDEFINE        &&  PJXConvert 
  3025.  
  3026.  
  3027. **********************************************
  3028. DEFINE CLASS FPCConverter AS PJXConverterBase
  3029. **********************************************
  3030.     *- class for converting 2.6 Catalog Files (FPC files)
  3031.     *- simpler file structure than projects
  3032.     *- files are converted individually -- just as if selecting
  3033.     *- each one by one
  3034.  
  3035.     *------------------
  3036.     PROCEDURE Init
  3037.     *------------------
  3038.         PARAMETER aParms
  3039.  
  3040.         *- temp until array stuff fixed
  3041.         PRIVATE tmparr
  3042.         LOCAL m.nct
  3043.             
  3044.         gOPJX = THIS
  3045.  
  3046.         SET ESCAPE ON
  3047.         ON ESCAPE DO EscHandler
  3048.  
  3049.         THIS.isproj = .F.        && not really a project
  3050.  
  3051.         THIS.nTimeStamp    = THIS.TStamp()
  3052.         THIS.pjxName    = aParms[4]
  3053.         THIS.pjxVersion = aParms[3]
  3054.         THIS.cBackDir    = aParms[1]
  3055.         THIS.lDevMode    = aParms[7]
  3056.         THIS.cCodeFile    = aParms[8]
  3057.         THIS.lLog        = aParms[9]
  3058.         THIS.cLogFile    = aParms[10]
  3059.         THIS.lBackup    = aParms[11]
  3060.         THIS.iPlatformCount    = aParms[12]
  3061.  
  3062.         THIS.cCurrentFile = THIS.pjxName
  3063.         THIS.cMemoExt = "FCT"
  3064.  
  3065.         IF THIS.lLog
  3066.             THIS.WriteLog(C_CONVLOG_LOC + THIS.pjxName + " [" + TTOC(DATETIME()) + "]","")
  3067.             THIS.WriteLog(C_CONVVERS_LOC + C_CONVERSION_LOC,"")
  3068.             THIS.WriteLog("","")
  3069.         ENDIF
  3070.  
  3071.         *- make a working copy of the PJX file, in case of transporting, so if
  3072.         *- user cancels, original will still be available
  3073.         *- this is here for compatibility with PJXConverter
  3074.         cTmpPjxName = ADDBS(JUSTPATH(THIS.pjxName)) + 'P' + LEFT(SYS(3),7) + ".FPC"
  3075.         COPY FILE (THIS.pjxName) TO (m.cTmpPjxName)
  3076.         IF FILE(FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  3077.             COPY FILE (FORCEEXT(THIS.pjxName,THIS.cMemoExt)) TO (FORCEEXT(m.cTmpPjxName,THIS.cMemoExt))
  3078.         ENDIF
  3079.         THIS.pjxName = m.cTmpPjxName
  3080.  
  3081.         THIS.pjx25Alias = THIS.OpenFile(THIS.pjxName)
  3082.         IF EMPTY(THIS.pjx25Alias)
  3083.             THIS.lHadError = .T.
  3084.             RETURN
  3085.         ENDIF
  3086.  
  3087.         *- Check for proper file format
  3088.         IF !(FCOUNT() = C_FPCFLDS AND FIELD(8) = "FOX_FILE")
  3089.             USE IN (THIS.pjx25Alias)
  3090.             THIS.lHadError=.T.
  3091.             =MESSAGEBOX(E_INVALFPC_LOC)
  3092.             RETURN
  3093.         ENDIF
  3094.  
  3095.         *- Add records from old CAT file
  3096.         SELECT (THIS.pjx25Alias)
  3097.         COUNT FOR !DELETED() AND INLIST(type,C_FPCSCREENTYPE,C_FPCLABELTYPE,C_FPCREPORTTYPE) TO THIS.nScreenSets
  3098.         THIS.nScreenSets = THIS.nScreenSets + 2
  3099.         THIS.curscxid = 1
  3100.  
  3101.         gOTherm.Update2(0,C_PROJTASK5_LOC)
  3102.         
  3103.         gOTherm.visible = .T.
  3104.  
  3105.         THIS.cBackDir = ADDBS(THIS.cBackDir)
  3106.         THIS.cHomeDir = ADDBS(JUSTPATH(THIS.pjxName))
  3107.  
  3108.         THIS.BackFiles("path", "scx|frx|lbx", C_CONVERT3c_LOC)    && backup screen, report & label files to back dir
  3109.         IF gOMaster.lHadError OR THIS.lHadError
  3110.             THIS.Cleanup
  3111.             THIS.lHadError = .T.
  3112.             RETURN .F.
  3113.         ENDIF
  3114.  
  3115.         gOTherm.Update2((THIS.curscxid/(THIS.nScreenSets + 1)) * 100,C_PROJTASK5_LOC)        && update therm with next task
  3116.     
  3117.     ENDPROC        &&    FPCConverter:Init
  3118.  
  3119.     *----------------------------------
  3120.     PROCEDURE Converter        && FPCConverter
  3121.     *----------------------------------
  3122.         *- convert FPC itself
  3123.         *- convert each of the objects in it
  3124.  
  3125.         PRIVATE i, z, oForm, cOld, cTmpFile
  3126.         PRIVATE g_platforms
  3127.         PRIVATE aParms,oConvObject
  3128.         LOCAL    iWhichPlat
  3129.         PRIVATE aPlatforms
  3130.  
  3131.         cOld = THIS.pjx25Alias
  3132.  
  3133.         *- Get record count for Thermometer
  3134.  
  3135.         *- External preprocessor hook
  3136.           THIS.PreForm
  3137.  
  3138.         *- Create new PJX file here
  3139.         THIS.CreatePJX
  3140.  
  3141.         *- Add records from old PJX file
  3142.         SELECT (THIS.pjx25Alias)
  3143.  
  3144.         SCAN FOR !DELETED()
  3145.  
  3146.             DO CASE
  3147.                 CASE type = C_FPCCATTYPE
  3148.                     THIS.WriteLog(SYS(2027,EVAL(cOld + '.path')),C_CONVMSG_LOC)
  3149.                 CASE type = C_FPCSCREENTYPE
  3150.                     THIS.curscxid = THIS.curscxid + 1
  3151.  
  3152.                     IF THIS.nScreenSets > 0
  3153.                         gOTherm.Update2((THIS.curscxid/THIS.nScreenSets) * 100,C_PROJTASK1_LOC)
  3154.                     ENDIF
  3155.  
  3156.                     * needed for GENSCRN stuff
  3157.                     DIMENSION g_platforms[1]
  3158.                     g_platforms = ""
  3159.  
  3160.                     *- simulate call from _converter
  3161.                     DIMENSION aParms[13]
  3162.                     aParms[ 2] = C_SCREENTYPEPARM        && file type
  3163.                     aParms[ 3] = THIS.pjxVersion        && file version
  3164.                     aParms[ 4] = ALLT(SYS(2027,path))    && FP30 file name
  3165.                     aParms[ 5] = .T.                    && platform only
  3166.                     aParms[ 6] = .F.                    && special effect
  3167.                     aParms[ 7] = THIS.lDevMode            && developer mode
  3168.                     aParms[ 8] = THIS.cCodeFile            && code file if dev mode
  3169.                     aParms[ 9] = THIS.llog                && create log file?
  3170.                     aParms[10] = THIS.cLogFile            && logfile name
  3171.                     aParms[12] = THIS.iPlatformCount    && current platform only?
  3172.                     *- some other values are set below, in the FOR ... NEXT loop
  3173.  
  3174.                     THIS.cStubFile = FORCEEXT(aParms[4],C_SPREXT)
  3175.                     THIS.cOutFile = aParms[4]
  3176.  
  3177.                     IF THIS.iPlatformCount > 1
  3178.                         *- convert multiple platforms in present
  3179.                         *- if multiple platforms, cycle through for each platform
  3180.                         DIMENSION aPlatforms[1]
  3181.                         aPlatforms[1] = ""
  3182.                         THIS.GetPlatformCount(aParms[4], @aPlatforms)
  3183.                         IF EMPTY(aPlatforms[1])
  3184.                             *- was unable to determine platforms
  3185.                             LOOP
  3186.                         ENDIF
  3187.                         IF ALEN(aPlatforms,1) > 1
  3188.                             IF ASCAN(aPlatforms,C_WINDOWS) > 0 AND ASCAN(aPlatforms,C_MAC) > 0
  3189.                                 *- both platforms are there
  3190.                                 aParms[12] = 2
  3191.                             ENDIF
  3192.                         ENDIF
  3193.                     ELSE
  3194.                         aPlatforms[1] = THIS.GetPlatForm()
  3195.                     ENDIF
  3196.  
  3197.                     FOR m.iWhichPlat = 1 TO aParms[12]
  3198.  
  3199.                         aParms[ 1] = ""                        && backup dir (not used)
  3200.                         aParms[13] = m.iWhichPlat
  3201.  
  3202.                         oConvObject = CREATE(THIS.scxConverterClass, @aParms,.F.,.F.,.T.,.T.)    && no backup, 
  3203.                                                                                                 && not a project, 
  3204.                                                                                                 && show ext transpo dlog
  3205.                                                                                                 && don;t compile (we do that all at once at the end)
  3206.                         IF TYPE("oConvObject") # 'O'
  3207.                             *- object was not created
  3208.                             THIS.lHadError = .T.
  3209.                                 THIS.WriteLog(SYS(2027,THIS.cOutFile),C_NOTCONVMSG_LOC)
  3210.                         ENDIF
  3211.  
  3212.                         IF !THIS.lHadError AND !oConvObject.lHadError 
  3213.                             IF !oConvObject.lConverted 
  3214.                                 oConvObject.Converter
  3215.                             ELSE
  3216.                                 *- still need to know .SPR file location though
  3217.                                 SELECT (THIS.pjx25Alias)
  3218.                                 *- create an SPR file from the stored SPR code
  3219.                                 SELECT (oConvObject.c25alias)
  3220.                                 GO TOP
  3221.                                 IF !EMPTY(user)
  3222.                                     COPY MEMO user TO (THIS.cStubFile)
  3223.                                     THIS.WriteLog(SYS(2027,THIS.cOutFile),C_FILECONV_LOC + C_CREATMSG_LOC)
  3224.                                     IF USED(oConvObject.c25alias)
  3225.                                         USE IN (oConvObject.c25alias)
  3226.                                     ENDIF
  3227.                                     THIS.EndLog(THIS.cOutFile)
  3228.                                 ELSE
  3229.                                     *- error            
  3230.                                     THIS.lHadError = .T.
  3231.                                     RELEASE oConvObject            && dispose of object
  3232.                                     LOOP                        && continue converting
  3233.                                 ENDIF
  3234.                             ENDIF
  3235.                         ENDIF
  3236.  
  3237.                     NEXT        && going through each platform
  3238.  
  3239.  
  3240.                     *- add records to PJX file
  3241.                     THIS.InsertSCX
  3242.  
  3243.                     RELEASE oConvObject
  3244.  
  3245.                 CASE type = C_FPCREPORTTYPE OR ;
  3246.                     type = C_FPCLABELTYPE
  3247.                     *- Initialize report object
  3248.                     *- simulate call from _converter
  3249.                     THIS.curscxid = THIS.curscxid + 1
  3250.  
  3251.                     IF THIS.nScreenSets > 0
  3252.                         gOTherm.Update2((THIS.curscxid/THIS.nScreenSets) * 100,C_PROJTASK2_LOC)
  3253.                     ENDIF
  3254.  
  3255.                     DIMENSION aParms[13]
  3256.                     aParms[ 1] = ""                        && backup dir (not used)
  3257.                     aParms[ 2] = "REPORT"                && file type
  3258.                     aParms[ 3] = THIS.pjxVersion        && file version
  3259.                     aParms[ 4] = ALLT(SYS(2027,path))    && FP30 file name
  3260.                     aParms[ 5] = .T.                    && platform only
  3261.                     aParms[ 6] = .F.                    && special effect
  3262.                     aParms[ 7] = THIS.lDevMode            && developer mode
  3263.                     aParms[ 8] = THIS.cCodeFile            && code file if dev mode
  3264.                     aParms[ 9] = THIS.llog                && create log file?
  3265.                     aParms[10] = THIS.cLogFile            && logfile name
  3266.  
  3267.                     THIS.f3files = aParms[4]
  3268.                     THIS.f2files = IIF(THIS.lBackup,THIS.cBackDir,"") + JUSTFNAME(STRTRAN(path,C_NULL))
  3269.                     oForm = CREATEOBJ(THIS.frxConverterClass, @aParms, .F.,.F.,.T.,.T.)
  3270.  
  3271.                     IF TYPE("oForm") # "O"
  3272.                         *- object wasn't created (?)
  3273.                         THIS.lHadError = .T.
  3274.                     ENDIF
  3275.  
  3276.                     IF !THIS.lHadError
  3277.                         IF !oForm.lHadError AND !THIS.lHadError
  3278.                             IF !oForm.lConverted
  3279.                                 *- only convert the unconverted
  3280.                                 oForm.Converter
  3281.                             ELSE
  3282.                                 THIS.WriteLog(SYS(2027,THIS.f3files),C_FILECONV_LOC + '.' + C_CRLF)
  3283.                                 IF USED(oForm.c25alias)
  3284.                                     USE IN (oForm.c25alias)
  3285.                                 ENDIF
  3286.                             ENDIF
  3287.                         ENDIF
  3288.                     ELSE
  3289.                         *- reset this flag
  3290.                         THIS.lHadError = .F.
  3291.                     ENDIF
  3292.  
  3293.                     INSERT INTO (THIS.new30alias) ;
  3294.                         (name,mainprog,type,timestamp,homedir,exclude,comments,key);
  3295.                         VALUES(EVAL(cOld + '.File_name'),;
  3296.                             .F.,;
  3297.                             IIF(EVAL(cOld + '.type') = C_FPCLABELTYPE,C_LABEL,C_REPORT),;
  3298.                             THIS.nTimeStamp,;
  3299.                             JUSTPATH(EVAL(cOld + '.path')),;
  3300.                             .F.,;
  3301.                             EVAL(cOld + '.Title') + C_NULL,;
  3302.                             UPPER(LEFT(JUSTSTEM(EVAL(cOld + '.path')),LEN(key))))
  3303.  
  3304.  
  3305.                 OTHERWISE
  3306.                     PRIVATE cType
  3307.                     m.cTmpFile = EVAL(cOld + '.path')
  3308.                     m.cType = EVAL(cOld + '.type')
  3309.                     m.cType = IIF(m.cType = C_FPCDBFTYPE,"D",;
  3310.                               IIF(m.cType = C_FPCCSQUERYTYPE OR ;
  3311.                                     m.ctype = C_FPCUPQUERYTYPE OR ;
  3312.                                     m.ctype = C_FPCSQLQUERYTYPE,"P",;
  3313.                               IIF(m.cType = C_FPCREPORTTYPE,"R",;
  3314.                               IIF(m.cType = C_FPCLABELTYPE,"B",;
  3315.                               IIF(m.cType = C_FPCPRGTYPE,"P",;
  3316.                               IIF(m.cType = C_FPCAPPTYPE,"Z","x"))))))
  3317.                     INSERT INTO (THIS.new30alias) ;
  3318.                         (name,type,timestamp,exclude,comments,key);
  3319.                         VALUES(m.cTmpFile,;
  3320.                             m.cType,;
  3321.                             THIS.nTimeStamp,;
  3322.                             .F.,;
  3323.                             EVAL(cOld + '.Title') + C_NULL,;
  3324.                             UPPER(LEFT(JUSTSTEM(m.cTmpFile),LEN(key))))
  3325.                     THIS.WriteLog(SYS(2027,m.cTmpFile),C_NOCONVMSG_LOC)
  3326.             ENDCASE
  3327.         ENDSCAN
  3328.  
  3329.         *- compile the SCX files
  3330.         THIS.CompileAllScx
  3331.  
  3332.         *- compile the FRX files
  3333.         THIS.CompileAllFRX
  3334.  
  3335.         *- Close project
  3336.         THIS.ClosePJX
  3337.  
  3338.         *- close up gOTherm
  3339.         gOTherm.Complete2
  3340.  
  3341.         gOPJX = .NULL.
  3342.  
  3343.         RETURN THIS.cFull30PJXName
  3344.  
  3345.     ENDPROC        && FPCConverter:Converter
  3346.  
  3347.  
  3348.     *----------------------------------
  3349.     PROCEDURE InsertSCX            && FPCConverter
  3350.     *----------------------------------
  3351.         *- add appropriate record(s) to 3.0 PJX file
  3352.         LOCAL cFileName
  3353.  
  3354.         cFileName = SYS(2014,THIS.cOutFile,DBF(THIS.new30alias))
  3355.  
  3356.         INSERT INTO (THIS.new30alias) ;
  3357.             (name,timestamp,type,exclude,comments,key);
  3358.             VALUES(;
  3359.                 m.cFileName + CHR(0),;
  3360.                 THIS.nTimeStamp,;
  3361.                 C_SCXTYPE,;
  3362.                 THIS.lExclude,;
  3363.                 EVAL(cOld + '.Title') + C_NULL,;
  3364.                 UPPER(LEFT(JUSTSTEM(THIS.cOutFile),LEN(key))))
  3365.  
  3366.         IF THIS.iPlatformCount > 1 AND aParms[12] > 1
  3367.             *- converting more than one platform (i.e., also Mac) so add Mac form record
  3368.             m.cFileName = JustStem(cFileName) + C_MACEXT + "." + JustExt(cFileName)
  3369.             INSERT INTO (THIS.new30alias) ;
  3370.                 (name,timestamp,type,exclude,comments,key);
  3371.                 VALUES(;
  3372.                     cFileName + CHR(0),;
  3373.                     THIS.nTimeStamp,;
  3374.                     C_SCXTYPE,;
  3375.                     THIS.lExclude,;
  3376.                     EVAL(cOld + '.Title') + C_NULL,;
  3377.                     UPPER(LEFT(JustStem(THIS.cOutFile) + C_MACEXT + JustExt(THIS.cOutFile),LEN(key))))
  3378.         ENDIF
  3379.  
  3380.         PJXConverterBase::InsertSCX
  3381.  
  3382.     ENDPROC        && FPCConverter:InsertSCX
  3383.  
  3384.  
  3385.     *------------------------------------
  3386.     PROCEDURE Cleanup                    && FPCConverter
  3387.     *------------------------------------
  3388.         *- this proc is called by Error, and tries to put things back the way they were
  3389.         *- for catalogs, the originals have the x2x type extension. They need to be renamed.
  3390.  
  3391.         IF USED(THIS.pjx25Alias)
  3392.             SELECT file_name, type FROM DBF(THIS.pjx25Alias) ;
  3393.                 WHERE type $ C_FPCSCREENTYPE + C_FPCREPORTTYPE + C_FPCLABELTYPE AND !DELETED() ;
  3394.                 INTO ARRAY tmparr
  3395.         ELSE
  3396.             _TALLY = 0
  3397.         ENDIF
  3398.  
  3399.         *- force deletion of any lingering temp screen or report files
  3400.         IF _TALLY > 0
  3401.             m.nTables = AUSED(au)
  3402.             FOR i = 1 TO m.nTables
  3403.                 IF LEFT(au[i,1],1) = "S" OR LEFT(au[i,1],1) = "F"
  3404.                     cTmpFname = DBF(au[i,1])
  3405.                     cExt = UPPER(JustExt(cTmpFname))
  3406.                     IF ASCAN(tmparr,UPPER(JustFName(cTmpFName))) > 0
  3407.                         *- oops -- it;s one of the real ones
  3408.                         LOOP
  3409.                     ENDIF
  3410.                     IF INLIST(cExt,C_SCXEXT,"FRX","LBX")
  3411.                         USE IN (au[i,1])
  3412.                         ERASE (cTmpFname)
  3413.                         ERASE FORCEEXT(cTmpFname,IIF(m.cExt = C_SCXEXT,C_SCTEXT,;
  3414.                             IIF(m.cExt = "FRX","FRT","LBT")))
  3415.                     ENDIF
  3416.                 ENDIF
  3417.             NEXT
  3418.         ENDIF
  3419.  
  3420.         CLOSE TABLES
  3421.         IF THIS.lBackUp
  3422.             FOR i = 1 TO _TALLY
  3423.                 m.cTmpFname = FULLPATH(ALLTRIM(IIF(AT(CHR(0),tmparr[m.i,1]) > 0,;
  3424.                     LEFT(tmparr[m.i,1],AT(CHR(0),tmparr[m.i,1])-1),tmparr[m.i,1])),THIS.cHomeDir)
  3425.                 IF FILE(m.cTmpFname)
  3426.                     DO CASE
  3427.                         CASE tmparr[m.i,1] = C_SCXTYPE
  3428.                             IF    FILE(m.cTmpFname) AND ;
  3429.                                 FILE(FORCEEXT(m.cTmpFname,C_SCTEXT)) AND ;
  3430.                                 FILE(FORCEEXT(m.cTmpFname,C_SCXBACKEXT)) AND ;
  3431.                                 FILE(FORCEEXT(m.cTmpFname,C_SCTBACKEXT))
  3432.                                 DELETE FILE (m.cTmpFname)
  3433.                                 DELETE FILE (FORCEEXT(m.cTmpFname,C_SCTEXT))
  3434.                                 RENAME (FORCEEXT(m.cTmpFname,C_SCXBACKEXT)) TO (m.cTmpFname)
  3435.                                 RENAME (FORCEEXT(m.cTmpFname,C_SCTBACKEXT)) TO (FORCEEXT(m.cTmpFname,C_SCTEXT))
  3436.                             ENDIF
  3437.                         CASE tmparr[m.i,1] = C_REPORT
  3438.                             IF    FILE(m.cTmpFname) AND ;
  3439.                                 FILE(FORCEEXT(m.cTmpFname,"LBT")) AND ;
  3440.                                 FILE(FORCEEXT(m.cTmpFname,C_LBXBACKEXT)) AND ;
  3441.                                 FILE(FORCEEXT(m.cTmpFname,C_LBTBACKEXT))
  3442.                                 DELETE FILE (m.cTmpFname)
  3443.                                 DELETE FILE (FORCEEXT(m.cTmpFname,"LBT"))
  3444.                                 RENAME (FORCEEXT(m.cTmpFname,C_LBXBACKEXT)) TO (m.cTmpFname)
  3445.                                 RENAME (FORCEEXT(m.cTmpFname,C_LBTBACKEXT)) TO (FORCEEXT(m.cTmpFname,"LBT"))
  3446.                             ENDIF
  3447.                         CASE tmparr[m.i,1] = C_LABEL
  3448.                             IF    FILE(m.cTmpFname) AND ;
  3449.                                 FILE(FORCEEXT(m.cTmpFname,"FRT")) AND ;
  3450.                                 FILE(FORCEEXT(m.cTmpFname,C_FRXBACKEXT)) AND ;
  3451.                                 FILE(FORCEEXT(m.cTmpFname,C_FRTBACKEXT))
  3452.                                 DELETE FILE (m.cTmpFname)
  3453.                                 DELETE FILE (FORCEEXT(m.cTmpFname,"FRT"))
  3454.                                 RENAME (FORCEEXT(m.cTmpFname,C_FRXBACKEXT)) TO (m.cTmpFname)
  3455.                                 RENAME (FORCEEXT(m.cTmpFname,C_FRTBACKEXT)) TO (FORCEEXT(m.cTmpFname,"FRT"))
  3456.                             ENDIF
  3457.                     ENDCASE
  3458.                 ENDIF && cTmpFname (new file) exists
  3459.             NEXT
  3460.  
  3461.             *-now, erase files in backup dir
  3462.             =ADIR(af,THIS.cBackDir + "*.*")
  3463.             IF TYPE("af") # 'U'
  3464.                 FOR i = 1 TO ALEN(af,1)
  3465.                     IF af[i,5] $ 'RD'
  3466.                         LOOP
  3467.                     ENDIF
  3468.                     DELETE FILE (THIS.cBackDir + af[i,1])
  3469.                 NEXT
  3470.                 RELEASE af
  3471.             ENDIF
  3472.             IF ADIR(af,THIS.cBackDir + "*.*") = 0
  3473.                 IF TYPE("af") = 'U'
  3474.                     RD (THIS.cBackDir)
  3475.                 ENDIF
  3476.             ENDIF
  3477.         ENDIF && THIS.lBackUp
  3478.  
  3479.         IF FILE(THIS.PJXname)
  3480.             DELETE FILE (THIS.PJXname)
  3481.         ENDIF
  3482.         IF FILE(FORCEEXT(THIS.PJXname,"PJT"))
  3483.             DELETE FILE (FORCEEXT(THIS.PJXname,"PJT"))
  3484.         ENDIF
  3485.         IF FILE(FORCEEXT(THIS.PJXname,"FCT"))
  3486.             DELETE FILE (FORCEEXT(THIS.PJXname,"FCT"))
  3487.         ENDIF
  3488.  
  3489.     ENDPROC                    && FPCConverter:Cleanup
  3490.  
  3491.     *------------------
  3492.     PROCEDURE ClosePJX        && FPCConverter
  3493.     *------------------
  3494.         m.cTmpFname = FULLPATH(THIS.cCurrentFile,THIS.cHomeDir)
  3495.     
  3496.         THIS.CloseFiles
  3497.  
  3498.         THIS.cFull30PJXName = FORCEEXT(m.cTmpFname,"PJX")
  3499.  
  3500.         *- get rid of temp file
  3501.         IF FILE(THIS.pjxName)
  3502.             DELETE FILE (THIS.pjxName)
  3503.         ENDIF
  3504.         IF FILE(FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  3505.             DELETE FILE (FORCEEXT(THIS.pjxName,THIS.cMemoExt))
  3506.         ENDIF
  3507.  
  3508.         *- get rid of original -- back-up has been saved away...
  3509.         IF THIS.lBackUp
  3510.             IF FILE(THIS.cCurrentFile)
  3511.                 DELETE FILE (THIS.cCurrentFile)
  3512.             ENDIF
  3513.             IF FILE(FORCEEXT(THIS.cCurrentFile,THIS.cMemoExt))
  3514.                 DELETE FILE (FORCEEXT(THIS.cCurrentFile,THIS.cMemoExt))
  3515.             ENDIF
  3516.         ENDIF
  3517.  
  3518.         IF FILE(THIS.cFull30PJXName)
  3519.             DELETE FILE (THIS.cFull30PJXName)
  3520.         ENDIF
  3521.         RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJX") TO (THIS.cFull30PJXName)
  3522.  
  3523.         IF FILE(FORCEEXT(m.cTmpFname,"PJT"))
  3524.             DELETE FILE (FORCEEXT(m.cTmpFname,"PJT"))
  3525.         ENDIF
  3526.         RENAME (ADDBS(JUSTPATH(m.cTmpFname)) + THIS.new30alias + ".PJT") TO (FORCEEXT(m.cTmpFname,"PJT"))
  3527.  
  3528.     ENDPROC        && FPCConverter:ClosePJX
  3529.  
  3530. ENDDEFINE        &&  FPCConverter
  3531.  
  3532. **********************************************
  3533. DEFINE CLASS SCXSingleScreenConverter AS ConverterBase
  3534. **********************************************
  3535.  
  3536.     *- If someone wants to do their own converter:
  3537.     *- create their own object classes, 
  3538.     *- sub-class this class, 
  3539.     *- store their object class names in these variables
  3540.  
  3541.     formclass        = "fp25form"
  3542.     labelclass        = "fp25lbl"
  3543.     sayclass        = "fp25say"
  3544.     lineclass        = "fp25line"
  3545.     shapeclass        = "fp25shape"
  3546.     editclass        = "fp25edit"
  3547.     getclass        = "fp25get"
  3548.     spinclass        = "fp25spin"
  3549.     cboxclass        = "fp25cbox"
  3550.     listclass        = "fp25list"
  3551.     popupclass        = "fp25popup"
  3552.     pictclass        = "fp25pict"
  3553.     radioclass        = "fp25radio"
  3554.     *-btnclass        = "fp25btn"
  3555.     btnclass        = "fp25btngrp"
  3556.     btngclass        = "fp25btngrp"
  3557.     *-invclass        = "fp25invbtn"
  3558.     invclass        = "fp25invgrp"
  3559.     invgclass        = "fp25invgrp"
  3560.     oleclass        = "fp25ole"
  3561.     datanavclass    = "fpdatanav"                && data navigation object & cursor object
  3562.     datanavRelationClass = "fpdatanavRelation"    && data navigation relation object
  3563.     
  3564.     specialfx = .T.                                && add special fx? (i.e., make controls 3D?)
  3565.  
  3566.     oConvForm = .NULL.
  3567.  
  3568.     *- Object instance variables
  3569.     nObjCount = 0
  3570.     cStubFile = ""
  3571.     scxcount = 0
  3572.     timestamp = 0
  3573.     cNewScx = ""                && New SCX file name
  3574.     isMultiPlat = .F.
  3575.     curPlat = ""
  3576.     savedPlat = ""                && the platform we save may not be the one we are on (VFP Mac SCX's always have WINDOWS)
  3577.     platform = ""
  3578.     parentName = ""
  3579.     cParms = ""                    && parameter statement -- if any
  3580.     formnum =  1
  3581.     fp3prop    = ""                && properties
  3582.     fp3method = ""                && methods
  3583.     GetBorder = .T.
  3584.     itse_expr = ""
  3585.     read_expr = ""
  3586.     wclause_expr = ""
  3587.     cWnameExpr = ""
  3588.     noReadExpr = .F.
  3589.     noReadPlainExpr = .F.
  3590.     fontsub = ""
  3591.     lMultiReads = .F.
  3592.     cBackDir = ""
  3593.     lUserCall = .T.
  3594.     projcall = .F.
  3595.     lHasDataNavObj = .F.
  3596.     lIndirectWinName = .F.
  3597.     cIndirectWinName = ""
  3598.     cFormName =""
  3599.     nDNOCount = 0
  3600.     nDNORecNo = 0                && remember record # of DataEnvironment (nee DNO) record
  3601.     lConverted = .F.            && catch scx's in 3.0 format
  3602.     cReadShow = ""                && collects code for SAYs that need to be refreshed
  3603.     nFSetRecno = 0                && formset record number
  3604.     nFormRecno = 0                && form record number
  3605.     cHeaderID = "Screen"        && UniqueID for header 1 record
  3606.     cDefineWin = ""                && DEFINE WINDOW command
  3607.     lHasInvis = .F.                && flag for if has invisible buttons
  3608.     cProcs = ""                    && accumulate Cleanup procs from multiple screens in set
  3609.     lHasIDX    = .F.                && IDX files used in environment?
  3610.     cMainCurs = ""                && alias of main table
  3611.     cWinNames = ""                && accumulate list of window names, to prevent duplicates
  3612.     iFormSetCtr = 0                && counter for formsets
  3613.     cFormSetName = ""            && formset name
  3614.  
  3615.     lhasSys16 = .F.                && does SYS(16) appear in code?
  3616.     lHasReturn = .F.            && code returns a value
  3617.     lNoCompile = .F.            && flag to determine whether to compile right away, or later, in batch
  3618.  
  3619.     iPlatformCount = 1            && how many platforms do we need to deal with?
  3620.     iWhichPlat = 1                && which platform are we doing?
  3621.  
  3622.     *- Arrays
  3623.     DIMENSION a_plat[1]
  3624.     a_plat = ""
  3625.     DIMENSION a_reads[8]
  3626.     a_reads = ""
  3627.     DIMENSION a_scx2files[1,3]
  3628.     a_scx2files = ""
  3629.     DIMENSION a_scx2alias[1]
  3630.     a_scx2alias = ""
  3631.     DIMENSION a_scx3files[1]
  3632.     a_scx3files = ""
  3633.     DIMENSION a_scx3alias[1]
  3634.     a_scx3alias = ""
  3635.     DIMENSION a_pjxsets[10]
  3636.     a_pjxsets= ""
  3637.  
  3638.     DIMENSION a_tables[1]
  3639.     DIMENSION a_torder[1]
  3640.     a_tables = ""
  3641.     a_torder = ""
  3642.  
  3643.     *------------------------------------
  3644.     PROCEDURE Init                && SCXSingleScreenConverter
  3645.     *------------------------------------
  3646.         PARAMETER aParms, lBackup, lProjCall, lForceTransportDlog, lNoCompile
  3647.  
  3648.         LOCAL m.imaxThisTime, m.imaxOtherTime
  3649.  
  3650.         THIS.oConvForm = THIS
  3651.  
  3652.         THIS.projcall = lProjCall
  3653.  
  3654.         THIS.lBackup = m.lBackup
  3655.  
  3656.         THIS.lTransDlog = lForceTransportDlog
  3657.  
  3658.         THIS.lNoCompile = lNoCompile
  3659.  
  3660.         THIS.lDevMode = aParms[7]
  3661.         THIS.cCodeFile = aParms[8]
  3662.         THIS.llog = aParms[9]
  3663.         THIS.cLogFile = aParms[10]
  3664.         THIS.iPlatformCount = MAX(aParms[12],1)
  3665.         THIS.iWhichPlat = aParms[13]
  3666.         THIS.savedPlat = C_WINDOWS                && always WINDOWS on VFP Mac (jd 03/27/96)
  3667.  
  3668.         PRIVATE j
  3669.  
  3670.         DIMENSION a_pjxsets[10]
  3671.         a_pjxsets= ""
  3672.  
  3673.         *- populate settings array with default options
  3674.         THIS.a_pjxsets[A_OPENFILES]  = IIF(THIS.projcall,gOPJX.a_pjxsets[A_OPENFILES],.T.)    && open DBF files
  3675.         THIS.a_pjxsets[A_CLOSEFILES] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_CloseFiles],.T.)    && close DBF files
  3676.         THIS.a_pjxsets[A_DEFWINDOWS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_DEFWINDOWS],.T.)    && define windows
  3677.         THIS.a_pjxsets[A_RELWINDOWS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_RELWINDOWS],.T.)    && release windows
  3678.         THIS.a_pjxsets[A_READMODAL]  = IIF(THIS.projcall,gOPJX.a_pjxsets[A_READMODAL],.F.)    && READ MODAL
  3679.         THIS.a_pjxsets[A_GETBORDERS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_GETBORDERS],.T.)    && border for GETs
  3680.         THIS.a_pjxsets[A_READCYCLE]  = IIF(THIS.projcall,gOPJX.a_pjxsets[A_READCYCLE],.T.)    && READ CYCLE
  3681.         THIS.a_pjxsets[A_READNOLOCK] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_READNOLOCK],.F.)    && READ NOLOCK
  3682.          THIS.a_pjxsets[A_MULTIREADS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_MULTIREADS],.F.)    && multiple READs
  3683.          THIS.a_pjxsets[A_ASSOCWINDS] = IIF(THIS.projcall,gOPJX.a_pjxsets[A_ASSOCWINDS],"")    && associated windows
  3684.         THIS.lMultiReads = THIS.a_pjxsets[A_MULTIREADS]
  3685.  
  3686.         THIS.lAutoClose = THIS.a_pjxsets[A_CLOSEFILES]
  3687.  
  3688.         IF THIS.projcall                                        && called from project
  3689.             THIS.cBackDir = gOPJX.cBackDir                        && used only for project
  3690.             DIMENSION THIS.a_scx2files[ALEN(gOPJX.a_s2files,1),3]
  3691.             DIMENSION THIS.a_scx3files[ALEN(gOPJX.a_s3files,1)]
  3692.             =ACOPY(gOPJX.a_s2files,THIS.a_scx2files)
  3693.             =ACOPY(gOPJX.a_s3files,THIS.a_scx3files)            
  3694.             THIS.cStubFile = gOPJX.cStubFile
  3695.             THIS.cNewScx = THIS.a_scx3files[1]
  3696.             IF !THIS.lMultiReads
  3697.                 DIMENSION THIS.a_scx3files[1]
  3698.             ENDIF
  3699.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  3700.         ELSE
  3701.             IF EMPTY(aParms[1])
  3702.                 THIS.lUserCall = .F.    && assume called without output file
  3703.                 aParms[1] = ADDBS(JUSTPATH(aParms[4])) + LEFT(SYS(3),7) + ".SCX"
  3704.                 THIS.cNewScx = aParms[4]
  3705.             ELSE
  3706.                 THIS.cNewScx = aParms[1]
  3707.             ENDIF
  3708.             THIS.a_scx3files[1] = aParms[1]
  3709.             THIS.cStubFile = FORCEEXT(THIS.cNewScx,C_SPREXT)
  3710.             DIMENSION THIS.a_scx2files[1,3]
  3711.             THIS.a_scx2files[1,1] = aParms[4]
  3712.             THIS.a_scx2files[1,2] = ""
  3713.             THIS.a_scx2files[1,3] = aParms[4]
  3714.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  3715.             *- go ahead and make backup now, before we start
  3716.             *- if screen needs to be transported, the original is around
  3717.             IF THIS.lBackUp
  3718.                 *- copy old screen with S2X,S2T extensions. No need to backup .SCR files
  3719.                 IF FILE(THIS.a_scx2files[1]) AND UPPER(JUSTEXT(THIS.a_scx2files[1])) = C_SCXEXT
  3720.                     COPY FILE (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  3721.                 ENDIF
  3722.                 IF FILE(FORCEEXT(THIS.a_scx2files[1],C_SCTEXT))
  3723.                     COPY FILE (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  3724.                 ENDIF
  3725.                 *- backup has been done
  3726.                 THIS.lBackUp = .F.
  3727.             ENDIF
  3728.         ENDIF
  3729.  
  3730.         gOTherm.SetTitle(C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  3731.         gOTherm.Update(0,"")
  3732.         gOTherm.visible = .T.
  3733.  
  3734.         THIS.platform = THIS.GetPlatForm(THIS.iWhichPlat)
  3735.  
  3736.         THIS.WriteLog("","")                    && force a blank line
  3737.         THIS.BeginLog(SYS(2027,THIS.cNewScx) + IIF(THIS.platform == C_MAC AND THIS.iPlatformCount > 1, " " + C_MACLOGMSG_LOC,""))
  3738.  
  3739.         THIS.nTimeStamp = THIS.TStamp()
  3740.         THIS.scxcount = ALEN(THIS.a_scx2files,1)
  3741.  
  3742.         DIMENSION THIS.a_scx2alias[THIS.scxcount]
  3743.  
  3744.         FOR j = 1 TO THIS.scxcount
  3745.  
  3746.             IF !THIS.KnownFile(THIS.a_scx2files[m.j,1])
  3747.                 *- unknown file format -- error has already been written to the log
  3748.                 THIS.oConvForm = .NULL.
  3749.                 IF !THIS.projcall
  3750.                     *- attempt to remove backup files (jd 04/16/96)
  3751.                     THIS.EraseBackup
  3752.                 ENDIF
  3753.                 RETURN .F.
  3754.             ENDIF
  3755.  
  3756.             *- also check Read-Only status if project call (04/15/96 jd)
  3757.             IF THIS.projcall AND pReadOnly(THIS.cNewSCX)
  3758.                 THIS.WriteLog(JUSTFNAME(THIS.cNewSCX),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  3759.                 RETURN .F.
  3760.             ENDIF
  3761.  
  3762.             *- now try to open SCX file -- returns alias
  3763.             THIS.a_scx2alias[m.j] = THIS.OpenFile(THIS.a_scx2files[m.j,1])
  3764.                 
  3765.             IF EMPTY(THIS.a_scx2alias[m.j])
  3766.                 *- error has been logged
  3767.                 THIS.oConvForm = .NULL.
  3768.                 IF !THIS.projcall
  3769.                     *- attempt to remove backup files (jd 04/16/96)
  3770.                     THIS.EraseBackup
  3771.                 ENDIF
  3772.                 RETURN .F.
  3773.             ENDIF
  3774.  
  3775.             IF j = 1
  3776.                 THIS.c25alias = THIS.a_scx2alias[m.j]
  3777.             ENDIF
  3778.  
  3779.             *- Check for file format
  3780.             DO CASE
  3781.                 CASE FCOUNT() = C_SCXFLDS AND FIELD(1) = "PLATFORM"
  3782.                     *- 2.5 SCX type
  3783.                     LOCATE FOR PLATFORM = THIS.platform
  3784.                     IF !FOUND()
  3785.                         *-  no platform objects for the current platform
  3786.                         IF !THIS.Conv20SCX(12)
  3787.                             THIS.lHadError = .T.
  3788.                             THIS.oConvForm = .NULL.
  3789.                             THIS.EraseBackup
  3790.                             RETURN
  3791.                         ENDIF
  3792.                     ELSE
  3793.                         *- check to see if any records are later than current platform records
  3794.                         *- if so, call transporter
  3795.                         CALCULATE MAX(timestamp) FOR platform = THIS.platform TO m.imaxThisTime
  3796.                         CALCULATE MAX(timestamp) FOR platform # THIS.platform TO m.imaxOtherTime
  3797.                         IF m.imaxOtherTime > m.imaxThisTime
  3798.                             IF !THIS.Conv20SCX(12)
  3799.                                 THIS.lHadError = .T.
  3800.                                 THIS.oConvForm = .NULL.
  3801.                                 THIS.EraseBackup
  3802.                                 RETURN
  3803.                             ENDIF
  3804.                         ENDIF
  3805.                     ENDIF
  3806.                 CASE FCOUNT() = C_20SCXFLDS AND FIELD(1) = "OBJTYPE"
  3807.                     *- 2.0 SCX type
  3808.                     *- Invoke Transporter
  3809.                     *- =MESSAGEBOX(E_HAS20FILE_LOC)
  3810.                     IF !THIS.Conv20SCX(2)
  3811.                         THIS.lHadError = .T.
  3812.                         THIS.oConvForm = .NULL.
  3813.                         THIS.EraseBackup
  3814.                         RETURN
  3815.                     ENDIF
  3816.                 CASE FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  3817.                     *- assume 3.0 format, screen was already converted
  3818.                     *- (this could be called while converting a 2.x Project
  3819.                     *- that contains scx's that have already been converted)
  3820.                     IF j = 1
  3821.                         *- some of the defaults for VFP 4.0 have changed. So if user
  3822.                         *- elected to retain the 3.0 behavior/defaults, we need to explicitly
  3823.                         *- write out those properties (05/14/96 jd)
  3824.                         *- this means that the checkbox is checked
  3825.                         IF !THIS.Set30Defaults()
  3826.                             THIS.lHadError = .T.
  3827.                             THIS.oConvForm = .NULL.
  3828.                             THIS.EraseBackup
  3829.                         ENDIF
  3830.                         THIS.lConverted = .T.    && only set this if main screen
  3831.                         RETURN
  3832.                     ELSE
  3833.                         *- screen is converted, but part of a screen set, so allow to continue
  3834.                     ENDIF
  3835.                 OTHERWISE
  3836.                     USE IN (THIS.a_scx2alias[m.j])
  3837.                     THIS.WriteLog(JUSTFNAME(THIS.a_scx2files[m.j,1]),TRIM(E_WRONGFMT_LOC) + E_NOCONVERT_LOC)
  3838.                     THIS.oConvForm = .NULL.
  3839.                     RETURN
  3840.             ENDCASE
  3841.         
  3842.         ENDFOR    && end of opening SCX files in set
  3843.         
  3844.         *- this cursor is for working with memo fields
  3845.         IF USED("_FOX3SPR")
  3846.           USE IN _FOX3SPR
  3847.         ENDIF
  3848.  
  3849.         CREATE CURSOR _FOX3SPR (sprmemo m, temp1 m, temp2 m, temp3 m, temp4 m,defines m, load m, code m)
  3850.         APPEND BLANK
  3851.         REPLACE _FOX3SPR.load WITH "PROCEDURE " + C_DELOAD_METH + C_CR, ;
  3852.             _FOX3SPR.code WITH C_CRLF + C_CODEHDR1_LOC + C_CODEHDR_LOC + THIS.a_scx2files[1,3] + C_CRLF + C_CODEHDR1_LOC + C_CRLF
  3853.  
  3854.         IF THIS.lDevMode AND THIS.projcall AND USED("_FOX3PJX")
  3855.             *- accumulate all of code in final screen
  3856.             REPLACE  _FOX3SPR.sprmemo WITH _FOX3PJX.sprmemo + C_CR
  3857.         ENDIF
  3858.  
  3859.         SELECT (THIS.c25alias)
  3860.  
  3861.     ENDPROC        &&  SCXSingleScreenConverter:Init
  3862.     
  3863.     *----------------------------------
  3864.     PROCEDURE Converter        && SCXSingleScreenConverter
  3865.     *----------------------------------
  3866.         PRIVATE i, j
  3867.         LOCAL oRec, nrec, cFormset
  3868.  
  3869.         *- Get platforms used in Screen Set
  3870.         *- returns total records to process for Thermometer
  3871.         THIS.nRecCount = THIS.ScanPlat(THIS.platform) * THIS.iPlatformCount        && accommodate doing multiple platforms
  3872.         THIS.nTmpCount = 1      && reset
  3873.  
  3874.         gOTherm.SetTitle(C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  3875.         gOTherm.Update(0)
  3876.  
  3877.         *- External preprocessor hook
  3878.           THIS.PreForm
  3879.  
  3880.         *- Create new SCX file(s) here
  3881.         *- Multiple files created if MultiReads option.
  3882.         THIS.CreateSCX
  3883.         THIS.new30alias = THIS.a_scx3alias[1]
  3884.  
  3885.         *- Add objects by platform
  3886.         FOR m.i = 1 TO 1        && ALEN(THIS.a_plat)
  3887.  
  3888.             *- Add environment info
  3889.             SELECT (THIS.c25alias)        && only check first file
  3890.  
  3891.             GO TOP
  3892.             IF environ
  3893.                 LOCATE FOR INLIST(objtype,2,3,4) AND platform = THIS.a_plat[m.i] 
  3894.                 IF FOUND()
  3895.                     THIS.AddSRecs(m.i,C_DNO)
  3896.                 ENDIF
  3897.             ENDIF
  3898.             
  3899.             *- check for indirect reference to window name (name expr)
  3900.             IF LEFT(name,1) = "("
  3901.                 *- indirect ref to window name
  3902.                 *- make up a munged name
  3903.                 m.ctmpname = ALLT(name)
  3904.                 THIS.cFormName = T_FORM + "1"
  3905.                 THIS.lIndirectWinName = .T.
  3906.                 THIS.cIndirectWinName = SUBS(m.ctmpname,2,LEN(m.ctmpname) - 2)
  3907.             ENDIF
  3908.  
  3909.             *- Create Screen Set object
  3910.             THIS.AddFSet(THIS.a_plat[m.i])
  3911.  
  3912.             gOTherm.Update(THIS.nTmpCount/THIS.nRecCount * 100)
  3913.  
  3914.             FOR m.j = 1 TO THIS.scxcount
  3915.  
  3916.                 *- Use separate files if Multi-Read option
  3917.                 IF THIS.lMultiReads
  3918.                     THIS.new30alias = THIS.a_scx3alias[m.j]
  3919.                 ENDIF
  3920.                 
  3921.                 *- Select screen to process in screen set
  3922.                 SELECT (THIS.a_scx2alias[m.j])
  3923.                 THIS.formnum = m.j
  3924.  
  3925.                 *- if this screen isn;t the main screen, it may already have been converted
  3926.                 *- so... just add the records to the main screen
  3927.                 IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  3928.                     *- this screen was already converted
  3929.                     LOCATE FOR class = T_FSET
  3930.                     m.cFormSet = objname
  3931.                     USE
  3932.                     SELECT (THIS.new30alias)
  3933.                     m.nRec = RECC()
  3934.                     APPEND FROM (THIS.cBackDir + THIS.a_scx2files[m.j,3]) FOR uniqueid # "Screen" AND uniqueid # "FONTINFO" AND LOWER(class) # "formset"
  3935.                     REPLACE ALL uniqueID WITH "~" + CHR(64 + j) FOR RECNO() > m.nrec
  3936.                     REPLACE ALL parent WITH STRTRAN(parent,m.cFormSet,THIS.cFormSetName)    && change formset to this formset
  3937.                     SELECT (THIS.c25alias)
  3938.                     LOOP
  3939.                 ENDIF
  3940.  
  3941.                 *- Add Screen objects
  3942.                 THIS.AddSRecs(m.i,C_CONTROLS)
  3943.                 IF THIS.lHadError    && RED00N4G
  3944.                     RETURN -1
  3945.                 ENDIF
  3946.             
  3947.                 *- collect procs for this screen
  3948.                 THIS.AddProcs1
  3949.  
  3950.                 IF m.j = 1 OR THIS.lMultiReads
  3951.                     *- Write FontInfo -- there is only a single record for 
  3952.                     *- FontInfo regardless of number of forms.
  3953.                     THIS.WriteFontSub()
  3954.                 ENDIF
  3955.  
  3956.                 IF m.j > 1 AND THIS.lMultiReads AND THIS.projcall
  3957.                     LOCAL m.cOldOutFile
  3958.                     m.cOldOutFile = goPJX.cOutFile
  3959.                     goPJX.cOutFile = THIS.a_scx3Files[j]
  3960.                     goPJX.InsertSCX(.T.)
  3961.                     goPJX.cOutFile = m.cOldOutFile
  3962.                 ENDIF
  3963.  
  3964.                ENDFOR  && end of screen loop
  3965.  
  3966.  
  3967.         ENDFOR    && end of platform loop
  3968.  
  3969.         *- Add stub file (SPR) statements
  3970.         SELECT (THIS.c25alias)
  3971.         THIS.AddParm
  3972.  
  3973.         *- Add Cleanup snippet procs/funcs code here for SPR file
  3974.         THIS.AddGenProcs
  3975.  
  3976.         *- add SAY refresh code into FormSet.ReadShow method
  3977.         THIS.UpdMethods
  3978.  
  3979.         *- External postprocessor hook
  3980.           THIS.PostForm
  3981.  
  3982.         *- Close screen files
  3983.         THIS.CloseFiles
  3984.  
  3985.         *- close up gOTherm
  3986.         IF THIS.iWhichPlat == THIS.iPlatformCount
  3987.             *- don;t stop thermometer unless we are really done...
  3988.             gOTherm.Complete
  3989.         ENDIF
  3990.  
  3991.         *- release the reference
  3992.         THIS.oConvForm = .NULL.
  3993.  
  3994.         *- write to log file
  3995.         THIS.EndLog(THIS.cNewScx + IIF(THIS.platform == C_MAC AND THIS.iPlatformCount > 1, " " + C_MACLOGMSG_LOC,""))
  3996.  
  3997.         RETURN THIS.a_scx2files[1,1]
  3998.  
  3999.     ENDPROC    && SCXSingleScreenConverter:Converter
  4000.  
  4001.     *------------------
  4002.     PROCEDURE EraseBackup            && SCXSingleScreenConverter
  4003.     *------------------
  4004.         IF FILE(FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4005.             ERASE (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4006.         ENDIF
  4007.         IF FILE(FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4008.             ERASE (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4009.         ENDIF
  4010.     ENDPROC
  4011.  
  4012.     *------------------
  4013.     PROCEDURE KnownFile            && SCXSingleScreenConverter
  4014.     *------------------
  4015.         *- verify that the file is a known format
  4016.         *- we only test for previous versions of FoxPro, .FMT files, and dBASE IV .scr files
  4017.         PARAMETER cFileName
  4018.  
  4019.         LOCAL oThis, cNewSCXName
  4020.         oThis = THIS
  4021.         cNewSCXName = m.cFileName
  4022.  
  4023.         *- does file exist?
  4024.         IF FILE(m.cFileName)
  4025.             *- can it be opened?
  4026.             IF Readable(m.cFileName)
  4027.                 *- is it a DBF?
  4028.                 IF !THIS.IsDBF(m.cFileName)
  4029.                     *- not a DBF, so try and migrate it
  4030.                     SET MESSAGE TO C_MIGRATEMSG_LOC
  4031.                     gOTherm.SetTitle(C_THERMMSG11_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  4032.                     IF !MigDB4(m.cFileName, @oThis)
  4033.                         THIS.WriteLog(JUSTFNAME(m.cFileName),E_NOMIG_LOC)
  4034.                         =MESSAGEBOX(E_WRONGFMT_LOC + " " + E_NOCONVERT_LOC)
  4035.                         THIS.lHadError=.T.
  4036.                         oThis = .NULL.
  4037.                         RETURN .F.
  4038.                     ELSE
  4039.                         *- go ahead and transport
  4040.                         IF FILE(FORCEEXT(m.cNewSCXName,C_SCXEXT)) AND FILE(FORCEEXT(m.cNewSCXName,C_SCTEXT))
  4041.                             *- assume migrated okay, so update names of files we are working with
  4042.                             THIS.a_scx2files[m.j,1] = FORCEEXT(m.cNewSCXName,C_SCXEXT)
  4043.                             THIS.cCurrentFile = THIS.a_scx2files[m.j,1]
  4044.                         ELSE
  4045.                             =MESSAGEBOX(E_NOMIG_LOC + " " + E_NOCONVERT_LOC)
  4046.                             THIS.lHadError=.T.
  4047.                             oThis = .NULL.
  4048.                             RETURN .F.
  4049.                         ENDIF
  4050.                         gOTherm.SetTitle(C_THERMMSG7_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  4051.                         gOTherm.Update(0,"")
  4052.                         LOCAL m.lOldScxShow
  4053.                         m.lOldScxShow = gAShowMe[N_TRANFILE_SCX,1]
  4054.                         gAShowMe[N_TRANFILE_SCX,1] = .F.
  4055.                         DO (gTransport) WITH THIS.cCurrentFile,12,.F.,gAShowMe, m.gOTherm,THIS.cCurrentFile
  4056.                         gAShowMe[N_TRANFILE_SCX,1] = m.lOldScxShow
  4057.                     ENDIF
  4058.                 ENDIF
  4059.             ENDIF
  4060.         ENDIF
  4061.         oThis = .NULL.
  4062.  
  4063.     ENDFUNC        && SCXSingleScreenConverter:KnownFile
  4064.  
  4065.     *------------------
  4066.     PROCEDURE CreateSCX            && SCXSingleScreenConverter
  4067.     *------------------
  4068.         PRIVATE m.cScxName,m.tmpalias,m.j
  4069.         *- Note: only create more than 1 new SCX table if 
  4070.         *- Multi-Read generate option is selected. Otherwise
  4071.         *- terminate at end of first loop.
  4072.         
  4073.         FOR m.j = 1 TO THIS.scxcount
  4074.             m.cScxName = THIS.a_scx3files[m.j]
  4075.             DIMENSION THIS.a_scx3alias[m.j]
  4076.  
  4077.             *- create new SCX file
  4078.             CREATE TABLE (m.cScxName) ;
  4079.                 (platform c(8),;
  4080.                 uniqueid c(10),;
  4081.                 timestamp n(10),;
  4082.                 class m,;
  4083.                 classloc m,;
  4084.                 baseclass m,;
  4085.                 objname m,;
  4086.                 parent m,;
  4087.                 properties m,;
  4088.                 protected m,;
  4089.                 methods m,;
  4090.                 objcode m,;
  4091.                 ole m,;
  4092.                 ole2 m,;
  4093.                 reserved1 m,;
  4094.                 reserved2 m,;
  4095.                 reserved3 m,;
  4096.                 reserved4 m,;
  4097.                 reserved5 m,;
  4098.                 reserved6 m,;
  4099.                 reserved7 m,;
  4100.                 reserved8 m,;
  4101.                 user m)
  4102.  
  4103.             m.tmpalias = ALIAS()
  4104.             THIS.a_scx3alias[m.j] = ALIAS()
  4105.  
  4106.             *- Add header comment record
  4107.             INSERT INTO (m.tmpalias) ;
  4108.                 (platform,uniqueid,reserved1);
  4109.                 VALUES ("COMMENT",THIS.cHeaderID,C_SCXVERSTAMP)
  4110.  
  4111.             IF !THIS.lMultiReads
  4112.                 EXIT
  4113.             ENDIF
  4114.         ENDFOR
  4115.  
  4116.     ENDPROC            && SCXSingleScreenConverter
  4117.     
  4118.     *------------------
  4119.     PROCEDURE Conv20SCX
  4120.     *------------------
  4121.     *- This converts a foreign scx to a 2.x current platform.
  4122.         PARAMETER m.scxtype
  4123.         *- m.scxtype = 12        && FP2.5 SCX format
  4124.         *- m.scxtype = 2        && FP2.0 SCX format
  4125.         LOCAL m.oldudfp
  4126.         LOCAL m.cOldMess
  4127.  
  4128.         USE IN (THIS.a_scx2alias[m.j])
  4129.         gOTherm.SetTitle(C_THERMMSG7_LOC + LOWER(PARTIALFNAME(THIS.a_scx2files[m.j,3],C_FILELEN)))
  4130.         m.oldudfp = SET("UDFP")
  4131.         SET UDFP TO REFERENCE
  4132.         m.cOldMess = SET("MESSAGE",1)
  4133.         DO (gTransport) WITH THIS.a_scx2files[m.j,1],m.scxtype,.F.,gAShowMe, m.gOTherm,THIS.a_scx2files[m.j,3],THIS.lTransDlog
  4134.         SET UDFP TO &oldudfp
  4135.         SET MESSAGE TO (cOldMess)
  4136.         THIS.a_scx2alias[m.j] = THIS.OpenFile(THIS.a_scx2files[m.j,1])
  4137.         THIS.c25alias = THIS.a_scx2alias[m.j]
  4138.         IF !EMPTY(THIS.a_scx2alias[m.j])
  4139.             IF FCOUNT() = C_SCXFLDS AND FIELD(1) = "PLATFORM"
  4140.                 LOCATE FOR Platform = THIS.Platform
  4141.                 IF FOUND()
  4142.                     RETURN .T.
  4143.                 ENDIF
  4144.             ENDIF
  4145.             USE IN (THIS.a_scx2alias[m.j])
  4146.         ENDIF
  4147.         THIS.lHadError=.T.
  4148.         RETURN .F.
  4149.     ENDPROC
  4150.  
  4151.     *------------------------------------
  4152.     PROCEDURE AddParm            && SCXSingleScreenConverter
  4153.     *------------------------------------
  4154.         PRIVATE j,cScxName
  4155.         LOCAL nParmCount, cParmCont, k, cParmCode, cParmA, npos
  4156.         LOCAL aTemp, cTmpText, cItem, nArryLen, cPubList, k, cDoForm
  4157.  
  4158.         cPubList = ""
  4159.  
  4160.         *- Base parameter statement on first SCX only in FP25.
  4161.         LOCATE FOR objtype = 1
  4162.         THIS.cParms = GetParam("setupcode")
  4163.         
  4164.         *- assume THIS.cParms was set in AddReads earlier
  4165.         IF !EMPTY(THIS.cParms)
  4166.             REPLACE _FOX3SPR.sprmemo WITH ;
  4167.                 C_PARM1_CMMT_LOC + ;
  4168.                 "PARAMETERS " + THIS.cParms + C_CRLF ADDITIVE
  4169.  
  4170.             *- need to add special code in case no parms passed, so 
  4171.             *- we don;t pass on default parms that shouldn;t be there
  4172.             m.nParmCount = OCCURS(",",THIS.cParms) + 1
  4173.             cParmCode = C_CRLF + ;
  4174.                         "LOCAL _aParm, _cparmstr, _nctr" + C_CRLF + ;
  4175.                         "DIMENSION _aParm[" + LTRIM(STR(nParmCount)) + "]" + C_CRLF
  4176.             *- assign parameter to an array, to build up a parameter clause to pass on
  4177.             m.npos = 1
  4178.             FOR m.k = 1 TO m.nParmCount
  4179.                 *- determine the parameter
  4180.                 IF m.k = m.nParmCount
  4181.                     cParmA = SUBS(THIS.cParms,npos)
  4182.                 ELSE
  4183.                     cParmA = SUBS(THIS.cParms,npos,AT(",",THIS.cParms,m.k) - npos)
  4184.                 ENDIF
  4185.                 m.cParmCode = m.cParmCode + ;
  4186.                         "_aParm[" + LTRIM(STR(m.k)) + "] = [" + ALLT(cParmA) + "]" + C_CRLF
  4187.                 m.npos = AT(",",THIS.cParms,m.k) + 1
  4188.             NEXT
  4189.  
  4190.             cParmCode = m.cParmCode + ;
  4191.                         C_CRLF + ;
  4192.                         "_cparmstr = []" + C_CRLF + ;
  4193.                         C_CRLF + ;
  4194.                         "IF PARAMETERS() > 0" + C_CRLF + ;
  4195.                         C_TAB + "_cparmstr = [WITH ]" + C_CRLF + ;
  4196.                         C_TAB + "_cparmstr = _cparmstr + _aParm[1]" + C_CRLF + ;
  4197.                         C_TAB + "FOR m._nctr = 2 TO PARAMETERS()" + C_CRLF + ;
  4198.                         C_TAB + C_TAB + "_cparmstr = _cparmstr + [,] + _aParm[m._nctr]" + C_CRLF + ;
  4199.                         C_TAB + "NEXT" + C_CRLF + ;
  4200.                         "ENDIF" + C_CRLF + C_CRLF
  4201.  
  4202.             REPLACE _FOX3SPR.SPRMEMO WITH cParmCode ADDITIVE
  4203.         ENDIF
  4204.  
  4205.         *- add in EXTERNAL lines
  4206.         IF !EMPTY(THIS.a_Dimes)
  4207.             m.nArryLen = ALEN(THIS.a_Dimes)
  4208.             FOR m.j = 1 TO m.nArryLen
  4209.                 *- expand array list (maybe multiple arrays were declared 
  4210.                 *- with one DIMENSION or DECLARE) (jd 03/11/96)
  4211.                 DECLARE a_Dimes2[1]
  4212.                 =GetArray(THIS.a_Dimes[j],@a_dimes2)
  4213.                 IF ALEN(a_dimes2,1) > 1
  4214.                     *- copy rest of array
  4215.                     THIS.a_Dimes[j] = a_dimes2[1]                                        && replace long item with just the first item
  4216.                     DIMENSION THIS.a_Dimes[ALEN(THIS.a_Dimes) + ALEN(a_dimes2,1) - 1]    && grow array
  4217.                     =ACOPY(a_dimes2, THIS.a_Dimes,2,-1,ALEN(THIS.a_Dimes) - ALEN(a_dimes2,1) + 2)    && 
  4218.                 ENDIF
  4219.             NEXT
  4220.             *- remove the array dimensions
  4221.             FOR m.j = 1 TO ALEN(THIS.a_Dimes)
  4222.                 THIS.a_Dimes[j] = StripParen(THIS.a_Dimes[j],'(',')')
  4223.                 THIS.a_Dimes[j] = StripParen(THIS.a_Dimes[j],'[',']')
  4224.             NEXT
  4225.             *- remove duplicates
  4226.             DECLARE aTemp[1]
  4227.             aTemp = ""
  4228.             m.nArryLen = 1
  4229.             FOR m.j = 1 TO ALEN(THIS.a_Dimes)
  4230.                 m.cTmpText = ALLT(THIS.a_Dimes[m.j])
  4231.                 IF ISALPHA(m.cTmpText) OR LEFT(m.cTmpText,1) == "_"
  4232.                     *- valid name (not a name expression)
  4233.                     m.cTmpText = ALLT(IIF("&" + "&" $ m.cTmpText,LEFT(m.cTmpText,AT("&" + "&",m.cTmpText) - 1), m.cTmpText))
  4234.                     m.cTmpText = ALLT(IIF(";" $ m.cTmpText,LEFT(m.cTmpText,AT(";",m.cTmpText) - 1), m.cTmpText))
  4235.                     DO WHILE !EMPTY(m.cTmpText)
  4236.                         IF "," $ m.cTmpText
  4237.                             m.cItem = LEFT(m.cTmpText,AT(",",m.cTmpText) - 1)
  4238.                             m.cTmpText = SUBS(m.cTmpText,AT(",",m.cTmpText) + 1)
  4239.                         ELSE
  4240.                             m.cItem = m.cTmpText
  4241.                             m.cTmpText = ""
  4242.                         ENDIF
  4243.                         IF !EMPTY(aTemp[1])
  4244.                             DIMENSION aTemp[m.nArryLen + 1]
  4245.                             m.nArryLen = m.nArryLen + 1
  4246.                         ENDIF
  4247.                         aTemp[m.nArryLen] = LOWER(ALLT(m.cItem))
  4248.                     ENDDO
  4249.                 ENDIF
  4250.             NEXT
  4251.  
  4252.             =ASORT(aTemp)
  4253.             m.cArrays = C_EXTERN_CMMT_LOC
  4254.             FOR m.j = 1 TO ALEN(aTemp)
  4255.                 IF m.j = 1 OR aTemp[m.j-1] != aTemp[m.j]
  4256.                     m.cArrays = m.cArrays + "EXTERNAL ARRAY " + aTemp[m.j] + C_CRLF
  4257.                 ENDIF
  4258.             NEXT
  4259.             REPLACE _FOX3SPR.SPRMEMO WITH m.cArrays + C_CRLF ADDITIVE
  4260.         ENDIF
  4261.  
  4262.         m.cScxName = THIS.cNewScx
  4263.         FOR m.j = 1 TO THIS.scxcount
  4264.             IF m.j # 1
  4265.                 m.cScxName = THIS.a_scx3files[m.j]
  4266.             ENDIF
  4267.             IF THIS.lHasReturn
  4268.                 REPLACE _FOX3SPR.SPRMEMO WITH C_RETVAL_CMMT_LOC + ;
  4269.                     "LOCAL _rval" + C_CRLF + C_CRLF ADDITIVE
  4270.             ENDIF
  4271.  
  4272.             IF THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES]
  4273.                 *- create PUBLIC variables for cursors, to hold record pointers
  4274.                 cPubList = C_GOTOVAR1_CMMT_LOC
  4275.                 FOR k = 1 TO ALEN(THIS.a_tables)
  4276.                     cCursVar = THIS.MakeVar(THIS.a_tables[k])
  4277.                     cPubList = m.cPubList + "PUBLIC " + m.cCursVar + C_CRLF
  4278.                 NEXT
  4279.                 REPLACE _FOX3SPR.SPRMEMO WITH ;
  4280.                     m.cPubList + C_CRLF ADDITIVE
  4281.             ENDIF
  4282.  
  4283.             IF !EMPTY(THIS.cParms)
  4284.                 cDoForm = [EXTERNAL PROC ] + JUSTFNAME(m.cScxName) + C_CRLF + C_CRLF + ;
  4285.                         IIF(THIS.iPlatformCount > 1,C_TAB,"") + [DO FORM "] + JUSTFNAME(m.cScxName) + [" NAME ] + SYS(2015) + [ LINKED ] + CHR(38) + "_cparmstr" + ;
  4286.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4287.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF)
  4288.                    IF THIS.iPlatformCount > 1
  4289.                      *- only write out filename, not full path
  4290.                     REPLACE _FOX3SPR.SPRMEMO WITH ;
  4291.                         [IF _mac] + C_CRLF + ;
  4292.                         C_TAB + [EXTERNAL PROC ] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + C_CRLF + C_CRLF + ;
  4293.                         C_TAB + [DO FORM "] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + ;
  4294.                             [" NAME ] + SYS(2015) + [ LINKED ] + CHR(38) + "_cparmstr" + ;
  4295.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4296.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF) + ;
  4297.                         [ELSE] + C_CRLF + ;
  4298.                         C_TAB + m.cDoForm + ;
  4299.                         [ENDIF] + C_CRLF ;
  4300.                         ADDITIVE
  4301.                 ELSE
  4302.                     REPLACE _FOX3SPR.SPRMEMO WITH m.cDoForm ADDITIVE
  4303.                 ENDIF
  4304.                ELSE
  4305.                    cDoForm = [EXTERNAL PROC ] + JUSTFNAME(m.cScxName) + C_CRLF + C_CRLF + ;
  4306.                         IIF(THIS.iPlatformCount > 1,C_TAB,"") + [DO FORM "] + JUSTFNAME(m.cScxName) + [" NAME ] + SYS(2015)+ [ LINKED ] + ;
  4307.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4308.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF)
  4309.                   IF THIS.iPlatformCount > 1
  4310.                        *- only write out filename, not full path
  4311.                      REPLACE _FOX3SPR.SPRMEMO WITH ;
  4312.                         [IF _mac] + C_CRLF + ;
  4313.                         C_TAB + [EXTERNAL PROC ] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + C_CRLF + C_CRLF + ;
  4314.                         C_TAB + [DO FORM "] + JUSTSTEM(m.cScxName) + C_MACEXT + "." + JUSTEXT(m.cScxName) + [" NAME ] + SYS(2015)+ [ LINKED ] + ;
  4315.                         IIF(THIS.noReadPlainExpr OR THIS.noReadExpr," NOREAD","") + ;
  4316.                         IIF(THIS.lHasReturn," TO m._rval" + C_CRLF + "RETURN m._rval" + C_CRLF,C_CRLF) + ;
  4317.                         [ELSE] + C_CRLF + ;
  4318.                         C_TAB + m.cDoForm + ;
  4319.                         [ENDIF] + C_CRLF ;
  4320.                         ADDITIVE
  4321.                 ELSE
  4322.                     REPLACE _FOX3SPR.SPRMEMO WITH m.cDoForm ADDITIVE
  4323.                 ENDIF
  4324.             ENDIF
  4325.  
  4326.             IF THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES]
  4327.                 *- add code to release public variables we created above
  4328.                 *cPubList = C_CRLF + C_GOTOVAR2_CMMT_LOC
  4329.                 *FOR k = 1 TO ALEN(THIS.a_tables)
  4330.                 *    cPubList = m.cPubList + "RELEASE " + THIS.MakeVar(THIS.a_tables[k]) + C_CRLF
  4331.                 *NEXT
  4332.                 *REPLACE _FOX3SPR.SPRMEMO WITH ;
  4333.                     m.cPubList + C_CRLF ADDITIVE
  4334.             ENDIF
  4335.  
  4336.             IF !THIS.lMultiReads
  4337.                 EXIT
  4338.             ENDIF
  4339.         ENDFOR
  4340.     ENDPROC        &&   AddParm
  4341.  
  4342.     *------------------
  4343.     PROCEDURE PostForm            && SCXSingleScreenConverter
  4344.     *------------------
  4345.         *- this is an external hook to postprocess
  4346.         *- form object
  4347.         
  4348.         *- make sure count of DNO items is recorded in DataNavigation
  4349.         *- object header record (in the Reserved2 field)
  4350.  
  4351.         LOCAL m.savearea, m.tempfile, cTemp, j
  4352.         m.savearea = SELECT()
  4353.  
  4354.         FOR j = 1 TO IIF(THIS.lMultiReads,THIS.scxCount,1)
  4355.             SELECT (THIS.a_scx3alias[j])
  4356.  
  4357.             IF THIS.nDNORecNo > 0 AND THIS.nDNOCount > 0
  4358.                 GO THIS.nDNORecNo
  4359.                 REPLACE reserved2 WITH LTRIM(STR(THIS.nDNOCount)),methods WITH IIF(THIS.lHasIDX,_FOX3SPR.load,methods)
  4360.             ENDIF
  4361.  
  4362.             *- record count of objects for each form in the SCX file
  4363.             LOCATE FOR class == C_FORMCLASS
  4364.  
  4365.             DO WHILE !EOF()
  4366.                 m.nFormRec1 = RECNO()                                            && remember form record #
  4367.                 SKIP                                                            && move past it
  4368.                 SCAN REST WHILE class # C_FORMCLASS AND !EMPTY(class)            && look for next form record, or fontinfo
  4369.                 ENDSCAN
  4370.                 m.nFormRec2 = RECNO()                                            && remember that record #
  4371.                 GO m.nformRec1                                                    && jump back to previous form record
  4372.                 REPLACE reserved2 WITH LTRIM(STR(m.nFormRec2 - m.nformRec1))    && store # of records
  4373.                 GO MIN(RECC(),m.nFormRec2)                                        && jump ahead to where we were...
  4374.                 IF !EOF()                                                        && and move past it
  4375.                     SKIP
  4376.                 ENDIF
  4377.             ENDDO    && going through file, tabulating #s of objects per form    && repeat
  4378.  
  4379.             *- sort on uniqueid
  4380.             IF THIS.lHasInvis
  4381.                 *- push all invisible buttons to end of file, so they will be created on top
  4382.                 *- pictures, since pictures will absorb mouse clicks in FP 3.0
  4383.  
  4384.                 *- create temporary file, and sort on uniqueID into it
  4385.                 REPLACE ALL uniqueID WITH "~Z" FOR uniqueID = "FONTINFO"
  4386.  
  4387.                 m.tempfile = ADDBS(JUSTPATH(THIS.a_scx3files[1])) + "S" + LEFT(SYS(3),7) +  "." + C_SCXEXT
  4388.                 SORT ON uniqueID TO (m.tempfile)
  4389.  
  4390.                 *- open the file, and change the unique ID for invisible buttons to a real uniqueID
  4391.                 SELECT 0
  4392.                 USE (m.tempfile)
  4393.                 REPLACE ALL uniqueid WITH SYS(2015) FOR "~A" $ uniqueid  OR '^' $ uniqueid
  4394.  
  4395.                 *- close the file, and replace the new SCX file with this modified one
  4396.                 USE
  4397.                 SELECT (THIS.a_scx3alias[j])
  4398.                 m.cTemp = DBF(THIS.a_scx3alias[j])
  4399.                 USE
  4400.                 DELETE FILE (m.cTemp)
  4401.                 DELETE FILE (FORCEEXT(m.cTemp,C_SCTEXT))
  4402.                 RENAME (m.tempfile) TO (m.cTemp)
  4403.                 RENAME (FORCEEXT(m.tempfile,C_SCTEXT)) TO (FORCEEXT(m.cTemp,C_SCTEXT))
  4404.  
  4405.                 *- reopen it
  4406.                 USE (m.cTemp)
  4407.             ENDIF
  4408.  
  4409.             *- and fix the FONTINFO record
  4410.             REPLACE ALL uniqueID WITH "FONTINFO" FOR "~Z" $ uniqueID
  4411.             REPLACE ALL uniqueID WITH SYS(2015) FOR "~" $ uniqueID
  4412.  
  4413.         NEXT
  4414.         SELECT (m.savearea)
  4415.  
  4416.     ENDPROC        && SCXSingleScreenConverter:PostForm            
  4417.  
  4418.     *------------------------------------
  4419.     PROCEDURE CloseFiles            && SCXSingleScreenConverter
  4420.     *------------------------------------
  4421.         PRIVATE i
  4422.         LOCAL cHFile, iCtr, cTmpFile
  4423.  
  4424.         IF USED("_FOX3SPR")
  4425.             SELECT (THIS.new30alias)
  4426.             GO TOP
  4427.             SELE _FOX3SPR
  4428.             IF !EMPTY(_FOX3SPR.defines)
  4429.                 *- write out #DEFINEs to new #INCLUDE file
  4430.                 cHFile = FORCEEXT(THIS.cStubFile,"h")
  4431.                 iCtr = 1
  4432.                 DO WHILE FILE(m.cHFile) AND m.iCtr <= 99
  4433.                     m.cHFile = FORCEEXT(THIS.cStubFile,"h" + RIGHT(STR(iCtr + 100),2))
  4434.                     m.iCtr = m.iCtr + 1
  4435.                 ENDDO
  4436.                 IF m.iCtr > 99
  4437.                     *- ?? very unlikely? go ahead and use original file
  4438.                     cHFile = FORCEEXT(THIS.cStubFile,"h")
  4439.                 ENDIF
  4440.                 REPLACE defines WITH C_CONV_CMMT_LOC + JustFName(m.cHFile) + C_CR + ;
  4441.                     C_H_CMMT_LOC + JustFName(THIS.cCurrentFile) + C_CR + C_CR + defines
  4442.                 COPY MEMO defines TO (m.cHFile)
  4443.                 *- remember the name of the #INCLUDE file
  4444.                 SELECT (THIS.new30alias)
  4445.                 REPLACE reserved8 WITH JUSTFNAME(m.cHFile)
  4446.                 *- add #INCLUDE to .SPR code
  4447.                 REPLACE _fox3spr.sprmemo WITH C_INCLUDE_CMMT_LOC + ;
  4448.                     "#INCLUDE " + JUSTFNAME(ALLT(reserved8)) + ;
  4449.                     C_CRLF + C_CRLF + _fox3spr.sprmemo
  4450.                 SELE _FOX3SPR
  4451.             ENDIF
  4452.             IF THIS.lDevMode
  4453.                 IF !EMPTY(_fox3spr.sprmemo)
  4454.                     REPLACE code WITH C_SEPARATOR + C_CODESRC_LOC + C_CRLF + _fox3spr.sprmemo ADDITIVE
  4455.                 ENDIF
  4456.                 IF !USED("_FOX3PJX")
  4457.                     *- write out code (it _FOX3PJX is used, it will be written out below)
  4458.                     COPY MEMO code TO (THIS.cCodeFile)
  4459.                 ENDIF
  4460.             ELSE 
  4461.                 COPY MEMO sprmemo TO (THIS.cStubFile)
  4462.             ENDIF
  4463.             *- remember SPR code, in case it needs to be spit out in the future
  4464.             SELECT (THIS.new30alias)
  4465.             REPLACE user WITH _fox3spr.sprmemo
  4466.             IF THIS.lDevMode AND THIS.projcall AND USED("_FOX3PJX")
  4467.                 REPLACE _FOX3PJX.sprmemo WITH _FOX3SPR.code
  4468.             ENDIF
  4469.  
  4470.             USE IN _FOX3SPR
  4471.         ENDIF
  4472.  
  4473.         FOR i = 1 TO ALEN(THIS.a_scx2alias)
  4474.             IF USED(THIS.a_scx2alias[m.i])
  4475.                 USE IN (THIS.a_scx2alias[m.i])
  4476.             ENDIF
  4477.         ENDFOR
  4478.  
  4479.         FOR m.i = 1 TO ALEN(THIS.a_scx3alias)
  4480.             IF USED(THIS.a_scx3alias[m.i])
  4481.                 USE IN (THIS.a_scx3alias[m.i])
  4482.             ENDIF
  4483.         ENDFOR
  4484.  
  4485.         *- if lUserCall = .T., means called via project
  4486.         *- if lUserCall = .F., means screen opened individually (also used for catalogs)
  4487.         IF THIS.lUserCall
  4488.             *- only thing we need to do with Project here is to change the
  4489.             *- name of the Mac form if converting all platforms and Mac
  4490.             *- platform is present... (12/16/95 jd)
  4491.             IF THIS.platform = C_MAC AND THIS.iPlatformCount > 1
  4492.                 m.cTmpFile = AddBS(JustPath(THIS.a_scx3files[1])) + ;
  4493.                     JustStem(THIS.a_scx3files[1]) + C_MACEXT + "." + C_SCXEXT
  4494.                 COPY FILE (THIS.a_scx3files[1]) TO (m.cTmpFile)
  4495.                 COPY FILE (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)) TO (FORCEEXT(m.cTmpFile,C_SCTEXT))
  4496.             ENDIF    
  4497.         ELSE
  4498.             IF THIS.lHadError
  4499.                 *- Delete temp files if we had an error
  4500.                 IF FILE(THIS.a_scx3files[1])
  4501.                     DELETE FILE (THIS.a_scx3files[1])
  4502.                     DELETE FILE FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)
  4503.                 ENDIF
  4504.             ELSE
  4505.                 IF THIS.lBackUp
  4506.                     *- erase existing backup file if it;s there
  4507.                     THIS.EraseBackUp
  4508.  
  4509.                     *- Rename old screen with S2X,S2T extensions
  4510.                     *- unless converting multiple platforms, and this one is Mac (need to leave original around 
  4511.                     *-   for Windows conversion) so copy.
  4512.                     IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  4513.                         COPY FILE (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4514.                         COPY FILE (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4515.                     ELSE
  4516.                         RENAME (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],C_SCXBACKEXT))
  4517.                         RENAME (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTBACKEXT))
  4518.                     ENDIF
  4519.                 ELSE
  4520.                     *- don;t delete if multi-platform and Mac, since we might need this later
  4521.                     IF !(THIS.platform = C_MAC AND THIS.iWhichPlat < THIS.iPlatformCount)
  4522.                         DELETE FILE (THIS.a_scx2files[1])
  4523.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT))
  4524.                     ENDIF
  4525.                 ENDIF
  4526.  
  4527.                 *- Rename new FP3 screen
  4528.                 IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  4529.                     *- converting more than one platform, and this one is Mac, so add _mac
  4530.                     *- extension to the file name
  4531.                     m.cTmpFile = (AddBS(JustPath(THIS.a_scx2files[1])) + ;
  4532.                         JustStem(THIS.a_scx2files[1]) + C_MACEXT + "." + C_SCXEXT)
  4533.                     IF FILE(m.cTmpFile)
  4534.                         *- erase it first
  4535.                         ERASE (m.cTmpFile)
  4536.                     ENDIF
  4537.                     RENAME (THIS.a_scx3files[1]) TO (m.cTmpFile)
  4538.                     IF FILE(FORCEEXT(m.cTmpFile,C_SCTEXT))
  4539.                         *- erase it first
  4540.                         ERASE (FORCEEXT(m.cTmpFile,C_SCTEXT))
  4541.                     ENDIF
  4542.                     RENAME (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)) TO (FORCEEXT(m.cTmpFile,C_SCTEXT))
  4543.                 ELSE
  4544.                     RENAME (THIS.a_scx3files[1]) TO (THIS.a_scx2files[1])
  4545.                     RENAME (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT)) TO (FORCEEXT(THIS.a_scx2files[1],C_SCTEXT))
  4546.                 ENDIF
  4547.  
  4548.                 *- Compile form
  4549.                 IF !THIS.lNoCompile
  4550.                     IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  4551.                         *- use proper name for Mac specific form
  4552.                         *- cTmpFile is set just above...
  4553.                         IF FILE(m.cTmpFile)
  4554.                             COMPILE FORM (m.cTmpFile)
  4555.                         ENDIF
  4556.                     ELSE
  4557.                         IF FILE(THIS.a_scx2files[1])
  4558.                             COMPILE FORM (THIS.a_scx2files[1])
  4559.                         ENDIF
  4560.                     ENDIF
  4561.                 ENDIF
  4562.  
  4563.             ENDIF
  4564.  
  4565.         ENDIF
  4566.  
  4567.     ENDPROC        &&   SCXSingleScreenConverter:CloseFiles
  4568.  
  4569.     *------------------------------------
  4570.     PROCEDURE Cleanup                && SCXSingleScreenConverter
  4571.     *------------------------------------
  4572.         *- this proc is called by Error, and tries to put things back the way they were
  4573.         *- if cleaning up from a crashed project conversion, the pjx cleanup will
  4574.         *- handle the screens
  4575.         LOCAL i
  4576.  
  4577.         IF !THIS.lUserCall 
  4578.             *- screen opened individually
  4579.             *- Delete temp files if we had an error
  4580.             CLOSE TABLES
  4581.             IF FILE(THIS.a_scx3files[1])
  4582.                 DELETE FILE (THIS.a_scx3files[1])
  4583.                 DELETE FILE (FORCEEXT(THIS.a_scx3files[1],C_SCTEXT))
  4584.             ENDIF
  4585.             IF !THIS.lBackUp
  4586.                 *- a backup could have already been made (e.g., a 2.0 file was being converted
  4587.                 *- restore old screen from S2X,S2T extensions
  4588.                 FOR i = 1 TO ALEN(THIS.a_scx2files,1)
  4589.                     IF    FILE(THIS.a_scx2files[i,1]) AND ;
  4590.                         FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT)) AND ;
  4591.                         FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCTEXT)) AND ;
  4592.                         FILE((FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT)))
  4593.                         *- all of the files are there to attempt this, so...
  4594.                         DELETE FILE (THIS.a_scx2files[i,1])
  4595.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[i],C_SCTEXT))
  4596.                         IF !FILE(THIS.a_scx2files[i,1])
  4597.                             RENAME (FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT)) TO (THIS.a_scx2files[i,1])
  4598.                         ENDIF
  4599.                         IF !FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCTEXT))
  4600.                             RENAME (FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT)) TO (FORCEEXT(THIS.a_scx2files[i,1],C_SCTEXT))
  4601.                         ENDIF
  4602.                     ENDIF
  4603.                     *- under certain circumstances, these may be left around
  4604.                     IF FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT))
  4605.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[i,1],C_SCXBACKEXT))
  4606.                     ENDIF
  4607.                     IF FILE(FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT))
  4608.                         DELETE FILE (FORCEEXT(THIS.a_scx2files[i,1],C_SCTBACKEXT))
  4609.                     ENDIF
  4610.                 NEXT
  4611.             ENDIF
  4612.         ENDIF
  4613.  
  4614.         THIS.oConvForm = .NULL.
  4615.  
  4616.     ENDPROC
  4617.  
  4618.     
  4619.     *---------------------------------------
  4620.     FUNCTION Set30Defaults            && SCXSingleScreenConverter
  4621.     *---------------------------------------
  4622.         *- set properties to VFP 3.0 defaults
  4623.         *- the following properties need to be set:
  4624.         *-        FontBold (default was bold in 3.0)
  4625.         *-        FontSize (default was 10 in 3.0)
  4626.         *-        ColorSource (default was 0 in 3.0)
  4627.         *-            Pages, pageframes  are set to 0
  4628.         *-            Forms are set to 5 (per allisonk 6/20/96)
  4629.         *- if the CLASSLOC field is not empty, that means the object has
  4630.         *- a parent, so we skip it -- it will pick up its behavior from one of
  4631.         *- its ancestors
  4632.  
  4633.         PRIVATE llUpdated, cProp
  4634.         LOCAL    cLine, cText, iRecc
  4635.  
  4636.         iRecc = RECC()
  4637.  
  4638.         SCAN FOR EMPTY(classloc)
  4639.  
  4640.             gOTherm.Update(RECNO()/iRecc * 100,C_PROJTASK6_LOC)        && update therm with next task
  4641.  
  4642.             llUpdated = .F.
  4643.             cProp = properties
  4644.  
  4645.             *- look for relevant properties in properties field
  4646.             *- if class is a container, look into the "contained" objects too
  4647.             IF INLIST(LOWER(baseclass), ;
  4648.                 "form","checkbox","combobox","commandbutton",;
  4649.                 "editbox","grid","header","label","listbox","page",;
  4650.                 "spinner","textbox")
  4651.                 IF !INLIST(LOWER(baseclass),"pageframe","formset")
  4652.                     *- check for, add FontBold and FontSize
  4653.                     THIS.Add40Property("FontBold",".T.","")
  4654.                     THIS.Add40Property("FontSize","10","")
  4655.                 ENDIF
  4656.             ENDIF
  4657.             
  4658.             IF INLIST(LOWER(baseclass), ;
  4659.                 "checkbox","combobox","commandbutton",;
  4660.                 "editbox","label","listbox","spinner",;
  4661.                 "shape","textbox","pageframe")
  4662.                 *- check for, add ColorSource
  4663.                 THIS.Add40Property("ColorSource","0","")
  4664.             ENDIF
  4665.  
  4666.             IF INLIST(LOWER(baseclass), ;
  4667.                 "commandgroup","optiongroup","grid","pageframe")
  4668.                 *- these are containers -- they will have sub-items (textboxes, 
  4669.                 *- optionbuttons, pages etc.) that will need to be checked
  4670.                 cText = m.cProp
  4671.                 FOR i = 1 TO MEMLINES(m.cProp)
  4672.                     cLine = MLINE(m.cText, ATCLINE(".name = ", m.cText))
  4673.                     cObject = LEFT(cLine, AT(".",cLine))
  4674.                     IF LOWER(baseclass) # "pageframe"
  4675.                         THIS.Add40Property("FontBold",".T.",cObject)
  4676.                         THIS.Add40Property("FontSize","10",cObject)
  4677.                     ENDIF
  4678.                     IF LOWER(baseclass) # "grid"
  4679.                         THIS.Add40Property("ColorSource","0",cObject)
  4680.                     ENDIF
  4681.                     cText = SUBS(cText,ATC(".name = ",cText) + 8)
  4682.                 NEXT
  4683.             ENDIF
  4684.             
  4685.             IF TRIM(LOWER(baseclass)) == "form"
  4686.                 *- check for, add ColorSource
  4687.                 THIS.Add40Property("ColorSource","5","")
  4688.             ENDIF
  4689.  
  4690.             IF m.llUpdated
  4691.                 REPLACE properties WITH m.cProp
  4692.             ENDIF
  4693.  
  4694.         ENDSCAN
  4695.  
  4696.         RETURN .T.
  4697.  
  4698.     ENDFUNC
  4699.     
  4700.     *---------------------------------------
  4701.     FUNCTION Add40Property            && SCXSingleScreenConverter
  4702.     *---------------------------------------
  4703.         PARAMETER lcProperty, lcValue, lcObject
  4704.  
  4705.         LOCAL iPos, lUseLF
  4706.         IF ATC(lcObject + lcProperty, m.cProp) == 0
  4707.             *- property is missing
  4708.             iPos = ATC(C_CRLF + m.lcObject + "name =",m.cProp)
  4709.             IF iPos == 0
  4710.                 lUseLF = .F.
  4711.                 iPos = ATC(C_CR + m.lcObject + "name =",m.cProp)
  4712.             ELSE
  4713.                 lUseLF = .T.
  4714.             ENDIF
  4715.             IF iPos # 0
  4716.                 m.cProp = LEFT(m.cProp,iPos - 1) + ;
  4717.                     IIF(m.lUseLF,C_CRLF,C_CR) + m.lcObject + lcProperty + " = " + lcValue + ;
  4718.                     SUBS(m.cProp,iPos)
  4719.                 llUpdated = .T.
  4720.             ENDIF
  4721.         ENDIF
  4722.     ENDFUNC
  4723.  
  4724.  
  4725.     *---------------------------------------
  4726.     PROCEDURE AddFontSub            && SCXSingleScreenConverter
  4727.     *---------------------------------------
  4728.         PRIVATE fontstr
  4729.         m.fontstr=ALLT(a_scx2fld[A_FONTFACE])+", "+ ;
  4730.             ALLT(STR(a_scx2fld[A_FONTSTYLE]))+", "+ ;
  4731.             ALLT(STR(a_scx2fld[A_FONTSIZE]))+", "+ ;
  4732.             ALLT(STR(a_scx2fld[A_HPOS]))+", "+ ;
  4733.             ALLT(STR(a_scx2fld[A_VPOS]))+", "+ ;
  4734.             ALLT(STR(a_scx2fld[A_HEIGHT]))+", "+ ;
  4735.             ALLT(STR(a_scx2fld[A_WIDTH]))+", "+ ;
  4736.             ALLT(STR(a_scx2fld[A_PENRED]))+", "+ ;
  4737.             ALLT(STR(a_scx2fld[A_PENGREEN]))+C_CRLF
  4738.         IF AT(m.fontstr,THIS.fontsub)=0
  4739.             THIS.fontsub = THIS.fontsub+m.fontstr
  4740.         ENDIF
  4741.     ENDPROC        &&   AddFontSub
  4742.     
  4743.     *---------------------------------------
  4744.     PROCEDURE WriteFontSub            && SCXSingleScreenConverter
  4745.     *---------------------------------------
  4746.           INSERT INTO (THIS.new30alias) ;
  4747.           (platform,uniqueid,properties) ;
  4748.           VALUES ("COMMENT","~Z",THIS.fontsub)
  4749.         THIS.fontsub = ""    &&reset
  4750.     ENDPROC        &&   WriteFontSub
  4751.     
  4752.     *------------------------------------
  4753.     PROCEDURE AddFSet            && SCXSingleScreenConverter
  4754.     *------------------------------------
  4755.         *-  Add the formset record here. We can use
  4756.         *-  "Formset1" name here since no 2.5 equivalent.
  4757.  
  4758.         PARAMETER getplat
  4759.         PRIVATE m.z,m.tmpstr,m.tmpcnt,m.j,lReadclause
  4760.         lReadclause = .F.
  4761.  
  4762.         THIS.curplat = m.getplat
  4763.  
  4764.         *- construct the formRef name
  4765.         THIS.iFormSetCtr = THIS.iFormSetCtr + 1
  4766.         THIS.cFormSetName = THIS.GetVarPrefix(T_FSET) + PROPER(LOWER(GoodName(JUSTSTEM(THIS.cCurrentFile)))) + LTRIM(STR(THIS.iFormSetCtr))
  4767.       
  4768.         *- reset arrays and all
  4769.         STORE "" TO THIS.a_reads
  4770.         THIS.nObjCount = 0
  4771.         THIS.fp3prop = ""        && properties
  4772.         THIS.fp3method = ""        && methods
  4773.  
  4774.         *- Add formset properties
  4775.       
  4776.         *- Add READ type here: Read - 2, Read Modal - 3
  4777.         IF THIS.lDevMode
  4778.             THIS.AddProp(M_READ,IIF(THIS.a_pjxsets[A_READMODAL],1,0))      
  4779.         ELSE
  4780.             THIS.AddProp(M_READ,IIF(THIS.a_pjxsets[A_READMODAL],3,2))      
  4781.         ENDIF
  4782.  
  4783.         *- Add READ CYCLE
  4784.           THIS.AddProp(M_READCYCLE,THIS.a_pjxsets[A_READCYCLE])      
  4785.       
  4786.         *- Add READ NOLOCK
  4787.           THIS.AddProp(M_READNOLOCK,!THIS.a_pjxsets[A_READNOLOCK])      
  4788.  
  4789.         *- GET Borders
  4790.           THIS.GetBorder = THIS.a_pjxsets[A_GetBorderS]
  4791.  
  4792.         *- Associated Windows
  4793.         IF !EMPTY(THIS.a_pjxsets[A_ASSOCWINDS])
  4794.             m.tmpstr = STRTRAN(THIS.a_pjxsets[A_ASSOCWINDS],CHR(13),',')
  4795.             THIS.AddProp(M_ASSOCWINDS,LEFT(m.tmpstr,LEN(m.tmpstr)-1))      
  4796.         ENDIF
  4797.  
  4798.         *- Accumulate READ stuff
  4799.         FOR m.j = 1 TO THIS.scxcount
  4800.  
  4801.             *- Select screen to process in screen set
  4802.             SELECT (THIS.a_scx2alias[m.j])
  4803.  
  4804.             *- already converted, so skip
  4805.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  4806.                 *- already converted, so skip this
  4807.                 LOOP
  4808.             ENDIF
  4809.  
  4810.             LOCATE FOR PLATFORM = THIS.curplat AND OBJTYPE = 1
  4811.             THIS.AddReads(m.j)
  4812.             
  4813.             *- RELEASE WINDOWS -- must be called after AddReads
  4814.             IF m.j = 1
  4815.                   THIS.AddProp(M_RELEASEWIND,THIS.a_pjxsets[A_RELWINDOWS])
  4816.             ENDIF
  4817.  
  4818.             *- Handle Multiple READ option
  4819.             IF THIS.lMultiReads
  4820.                 IF !EMPTY(THIS.read_expr)
  4821.                       THIS.ReadClause
  4822.                 ENDIF
  4823.  
  4824.                 *- Add Read snippets to Methods clause
  4825.                 THIS.WriteReads
  4826.                 
  4827.                 *- Add formset name
  4828.                 THIS.AddProp(M_NAME,THIS.cFormSetName)    && formset name
  4829.  
  4830.                 IF THIS.lDevMode
  4831.                     INSERT INTO (THIS.a_scx3alias[m.j]) ;
  4832.                       (platform,uniqueid,timestamp,;
  4833.                       class,baseclass,objname,properties) ;
  4834.                       VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4835.                       T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop)
  4836.                     IF !EMPTY(THIS.fp3method)
  4837.                         REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.cFormSetName + C_CRLF + THIS.fp3method ADDITIVE
  4838.                     ENDIF
  4839.                 ELSE
  4840.                     INSERT INTO (THIS.a_scx3alias[m.j]) ;
  4841.                       (platform,uniqueid,timestamp,;
  4842.                       class,baseclass,objname,properties,methods) ;
  4843.                       VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4844.                       T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop,THIS.fp3method)
  4845.                 ENDIF
  4846.  
  4847.                 IF m.j = 1
  4848.                     THIS.nFSetRecno = RECNO(THIS.a_scx3alias[1])
  4849.                 ENDIF
  4850.  
  4851.                 STORE "" TO THIS.a_reads
  4852.                 THIS.fp3method = ""            && methods
  4853.             ELSE
  4854.                 *- Check for #READCLAUSE
  4855.                 IF !EMPTY(THIS.read_expr) AND !m.lReadclause 
  4856.                     THIS.ReadClause
  4857.                     m.lReadclause= .T.
  4858.                 ENDIF
  4859.             ENDIF
  4860.         ENDFOR
  4861.  
  4862.         THIS.new30alias = THIS.a_scx3alias[1]
  4863.  
  4864.         IF !THIS.lMultiReads
  4865.             *- Add Read snippets to Methods clause
  4866.             THIS.WriteReads
  4867.  
  4868.             *- Add formset name
  4869.             THIS.AddProp(M_NAME,THIS.cFormSetName)    && default name
  4870.  
  4871.             IF THIS.lDevMode
  4872.                 *- put methods someplace else
  4873.                 INSERT INTO (THIS.new30alias) ;
  4874.                   (platform,uniqueid,timestamp,;
  4875.                   class,baseclass,objname,properties,reserved4) ;
  4876.                   VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4877.                   T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop,;
  4878.                   IIF(!THIS.a_pjxsets[A_DEFWINDOWS],"NODEFINE",""))
  4879.                 IF !EMPTY(THIS.fp3method)
  4880.                     REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.cFormSetName + C_CRLF + THIS.fp3method ADDITIVE
  4881.                 ENDIF
  4882.             ELSE
  4883.                 INSERT INTO (THIS.new30alias) ;
  4884.                   (platform,uniqueid,timestamp,;
  4885.                   class,baseclass,objname,properties,methods,reserved4) ;
  4886.                   VALUES (THIS.savedPlat,sys(2015),THIS.nTimeStamp,;
  4887.                   T_FSET,T_FSET,THIS.cFormSetName,THIS.fp3prop,THIS.fp3method,;
  4888.                   IIF(!THIS.a_pjxsets[A_DEFWINDOWS],"NODEFINE",""))
  4889.             ENDIF
  4890.  
  4891.             THIS.nFSetRecno = RECNO(THIS.a_scx3alias[1])
  4892.  
  4893.         ENDIF
  4894.  
  4895.         THIS.parentName = THIS.cFormSetName
  4896.     
  4897.         *- Select 1st screen
  4898.         SELECT (THIS.c25alias)
  4899.         
  4900.     ENDPROC        && AddFSet
  4901.  
  4902.  
  4903.     *------------------------------------------------
  4904.     PROCEDURE ReadClause            && SCXSingleScreenConverter
  4905.     *------------------------------------------------
  4906.     *- ReadClause -- process if #READ
  4907.     PRIVATE tmpstr,tmpcnt 
  4908.  
  4909.     *- Add READ MOUSE
  4910.     IF ATC("NOMOUSE",THIS.read_expr) # 0
  4911.         THIS.AddProp(M_READNOMOUSE,C_TRUE)      
  4912.     ENDIF
  4913.  
  4914.     *- Add READ SAVE
  4915.     IF ATC("SAVE",THIS.read_expr) # 0
  4916.         THIS.AddProp(M_READSAVE,C_TRUE)      
  4917.     ENDIF
  4918.  
  4919.     *- Add READ TIMEOUT
  4920.     IF ATC("TIME",THIS.read_expr) # 0
  4921.         m.tmpstr = SUBSTR(THIS.read_expr,ATC("TIME",THIS.read_expr))
  4922.         THIS.AddProp(M_READTIME,VAL(SUBSTR(m.tmpstr ,ATC(" ",m.tmpstr))) * K_TIMEOUT_FACTOR)  
  4923.     ENDIF
  4924.   
  4925.     *- Add READ OBJECT
  4926.     IF ATC("OBJECT",THIS.read_expr) # 0
  4927.         m.tmpstr = SUBSTR(THIS.read_expr,ATC("OBJECT",THIS.read_expr))
  4928.         THIS.AddProp(M_READOBJ,VAL(SUBSTR(m.tmpstr ,ATC(" ",m.tmpstr))))  
  4929.     ENDIF
  4930.  
  4931.     *- Color Scheme
  4932.     IF ATC("COLORSCHEME",THIS.read_expr) # 0
  4933.         m.tmpcnt = 1
  4934.         DO WHILE UPPER(WORDNUM(THIS.read_expr,m.tmpcnt))#"COLORSCHEME"
  4935.             m.tmpcnt = m.tmpcnt+1
  4936.         ENDDO
  4937.         m.tmpstr = WORDNUM(THIS.read_expr,m.tmpcnt+1)
  4938.         THIS.AddProp(M_SCHEME,m.tmpstr)
  4939.     ENDIF
  4940.  
  4941.     ENDPROC        && SCXSingleScreenConverter:ReadClause
  4942.     
  4943.     *------------------------------------------------
  4944.     PROCEDURE WriteReads            && SCXSingleScreenConverter
  4945.     *------------------------------------------------
  4946.         *- This routine writes the Methods field to the
  4947.         *- new 3.0 SCX file for the Formset record at
  4948.         *- the end since it combines the snippets of
  4949.         *- 2.5 screens from screen sets. 
  4950.         
  4951.         *- if #NOREAD PLAIN, toss any snippets
  4952.         DO CASE
  4953.             CASE THIS.noReadExpr
  4954.                 THIS.AddMethods(M_WHEN,THIS.a_reads[4],1)
  4955.                 THIS.AddMethods(M_VALID,THIS.a_reads[5],1)
  4956.                 THIS.AddMethods(M_ACTIVATE,THIS.a_reads[7],1)
  4957.                 THIS.AddMethods(M_DEACTIVATE,THIS.a_reads[8],1)
  4958.             CASE !THIS.noReadPlainExpr
  4959.                 THIS.AddMethods(M_WHEN,THIS.a_reads[4],1)
  4960.                 THIS.AddMethods(M_VALID,THIS.a_reads[5],1)
  4961.                 THIS.AddMethods(M_ACTIVATE,THIS.a_reads[7],1)
  4962.                 THIS.AddMethods(M_DEACTIVATE,THIS.a_reads[8],1)
  4963.             OTHERWISE
  4964.                 THIS.cProcs = THIS.cProcs + THIS.a_reads[3]
  4965.         ENDCASE
  4966.         
  4967.     ENDPROC        && WriteReads
  4968.  
  4969.     *------------------------------------
  4970.     PROCEDURE AddReads            && SCXSingleScreenConverter
  4971.     *------------------------------------
  4972.         PARAMETER scrn_num
  4973.         *- This routine updates the Methods field in the
  4974.         *- new 3.0 SCX file. Since 2.5 screen sets combine
  4975.         *- these, we will combine here as well and update
  4976.         *- the formset record at the end.
  4977.  
  4978.         PRIVATE m.part1,m.part2,m.part2line,m.part2chr
  4979.         PRIVATE m.sect1,m.sect2,m.sect1line,m.sect2line,m.parmline 
  4980.         PRIVATE m.sect1chr,m.sect2chr,m.sect2start
  4981.         PRIVATE m.gendir,m.gendircount,savearea
  4982.         PRIVATE m.j
  4983.         LOCAL m.ctemptxt, ngendir
  4984.         LOCAL cDefine, cTmp, nCtr, cReplaceStr, cGenAction, cParmLine, nCtr, nLine
  4985.  
  4986.         STORE "" TO m.part1,m.part2,m.sect1,m.sect2    
  4987.         STORE 0 TO m.part2line,m.part2chr
  4988.         STORE 0 TO m.sect1line,m.sect2line,m.parmline
  4989.         STORE 0 TO m.sect1chr,m.sect2chr,m.sect2start
  4990.         STORE 1 TO m.gendircount
  4991.         STORE SELECT() TO m.savearea
  4992.         
  4993.         *- Get parameter statement here -- assume we always
  4994.         *- hit here at least once
  4995.         THIS.cParms = GetParam("setupcode")
  4996.  
  4997.         *- Preprocess here for screen directives
  4998.         *- Also remove (comment out) others
  4999.         
  5000.         REPLACE _FOX3SPR.temp1 WITH setupcode
  5001.  
  5002.         SELECT _FOX3SPR
  5003.         *- go ahead and strip out leading white space here, so MemoFind doesn;t need to do it each time
  5004.         *- temp4 will be a "cleaned-up" version of temp1, to aid in finding the right directives
  5005.         REPLACE temp4 WITH CleanWhite(temp1)
  5006.  
  5007.         *- alter references to SYS(16), because they will now be in a procedure
  5008.         IF "SYS(16" $ UPPER(_FOX3SPR.temp1)
  5009.             REPLACE _FOX3SPR.temp1 WITH STRTRAN(_FOX3SPR.temp1,"SYS(16","_SYS(16")
  5010.             REPLACE _FOX3SPR.temp1 WITH STRTRAN(_FOX3SPR.temp1,"sys(16","_sys(16")
  5011.             REPLACE _FOX3SPR.temp1 WITH STRTRAN(_FOX3SPR.temp1,"Sys(16","_Sys(16")
  5012.             THIS.lhasSys16 = .T.
  5013.         ENDIF
  5014.  
  5015.         DO WHILE .T.
  5016.             m.gendir = MemoFind("#","temp4",.T.,.F.,m.gendircount,.T.,.T.)
  5017.             DO CASE
  5018.                 CASE m.gendir = C_NULL
  5019.                     EXIT
  5020.                 CASE UPPER(LEFT(m.gendir,4)) = "DEFI"
  5021.                     *- accumulate
  5022.                     IF RIGHT(TRIM(m.gendir),1) = ";"
  5023.                         *- a continued #DEFINE, so take some special measures
  5024.                         m.cDefine = ""
  5025.                         m.ngendir = MemoFind("#","temp4",.T.,.T.,m.gendircount,.T.,.T.)
  5026.                         IF m.ngendir = 0
  5027.                             *- this should be an impossibility -- couldn;t find where it was
  5028.                             EXIT
  5029.                         ENDIF
  5030.                         gendir = MLINE(temp1,m.ngendir)
  5031.                         *- check for continued #DEFINES
  5032.                         m.nCtr = 1
  5033.                         DO WHILE .T.
  5034.                             m.cDefine = m.cDefine + m.gendir + C_CRLF
  5035.                             IF RIGHT(m.gendir,1) # ";"
  5036.                                 EXIT
  5037.                             ELSE
  5038.                                 m.gendir = MLINE(temp1,m.ngendir + m.nCtr)
  5039.                                 m.nCtr = m.nCtr + 1
  5040.                             ENDIF
  5041.                         ENDDO
  5042.                         REPLACE _FOX3SPR.defines WITH m.cDefine ADDITIVE
  5043.                     ELSE
  5044.                         REPLACE _FOX3SPR.defines WITH ;
  5045.                           "#" + m.gendir + C_CRLF ADDITIVE
  5046.                     ENDIF
  5047.                 CASE UPPER(LEFT(m.gendir,2)) = "IF" ;
  5048.                   OR UPPER(LEFT(m.gendir,4)) = "ELSE" ;
  5049.                   OR UPPER(LEFT(m.gendir,4)) = "ELIF" ;
  5050.                   OR UPPER(LEFT(m.gendir,5)) = "ENDIF"
  5051.                   *- should accumulate these in with the defines, plus leave them in the methods
  5052.                     REPLACE _FOX3SPR.defines WITH ;
  5053.                       "#" + m.gendir + C_CRLF ADDITIVE
  5054.                     m.gendircount = m.gendircount + 1
  5055.                     LOOP
  5056.                 CASE UPPER(LEFT(m.gendir,4)) = "INSE" ;
  5057.                   OR UPPER(LEFT(m.gendir,4)) = "SECT"
  5058.                     m.gendircount = m.gendircount + 1
  5059.                     LOOP
  5060.                 CASE UPPER(LEFT(m.gendir,4)) = "ITSE"
  5061.                     THIS.itse_expr = UPPER(MemoFind("#ITSE","temp4",.T.,.F.))
  5062.                 CASE UPPER(LEFT(m.gendir,4)) = "READ"
  5063.                     THIS.read_expr = m.gendir
  5064.                 CASE UPPER(LEFT(m.gendir,7)) = "WCLAUSE"
  5065.                     THIS.wclause_expr = m.gendir
  5066.                 CASE UPPER(LEFT(m.gendir,5)) = "WNAME"
  5067.                     THIS.cWnameExpr = UPPER(MemoFind("#WNAME","temp4",.T.,.F.))
  5068.                 CASE UPPER(LEFT(m.gendir,6)) = "NOREAD" AND ATC("PLAIN",m.gendir) # 0
  5069.                     THIS.a_pjxsets[A_DEFWINDOWS] = .F.
  5070.                     THIS.a_pjxsets[A_RELWINDOWS] = .F.
  5071.                     THIS.noReadPlainExpr = .T.
  5072.                 CASE UPPER(LEFT(m.gendir,6)) = "NOREAD"
  5073.                     THIS.a_pjxsets[A_RELWINDOWS] = .F.
  5074.                     THIS.noReadExpr = .T.
  5075.             ENDCASE
  5076.             *- Comment out directive
  5077.             m.cGenAction = IIF(" " $ ALLT(m.gendir), ;
  5078.                 SUBS(m.gendir, AT(" ",LTRIM(m.gendir)) + 1),"")
  5079.             IF LEFT(LTRIM(m.cGenAction),1) = "&" AND ;
  5080.                 IIF(LEN(m.cGenAction) > 1,SUBS(m.cGenAction,2,1)," ") # "&"
  5081.                 *- a macro expression -- can;t handle it
  5082.                 *- log it, and comment it in file 
  5083.                 THIS.WriteLog(THIS.cCurrentFile,E_MACROEXPR1_LOC)
  5084.                 m.cReplaceStr = C_MACRO_CMMT_LOC + '*'
  5085.             ELSE
  5086.                 m.cReplaceStr = '*'
  5087.             ENDIF
  5088.             *- Comment out directive
  5089.             _MLINE = 0
  5090.             nLine = MemoFind("#","temp4",.T.,.T.,m.gendircount,.F.,.T.)
  5091.             cTmp = MLINE(temp1,nLine - 1)                        && set _MLINE
  5092.             REPLACE temp1 WITH STUFF(temp1,_MLINE + IIF(nLine <= 1,0,2),0,m.cReplaceStr)
  5093.             cTmp = MLINE(temp4,nLine - 1)                        && set _MLINE
  5094.             REPLACE temp4 WITH STUFF(temp4,_MLINE + IIF(nLine <= 1,0,1),0,m.cReplaceStr)
  5095.         ENDDO
  5096.         
  5097.         *- Get SETUP snippet SECTION 1 location
  5098.         *- If parameter statement, then we must start at 1st
  5099.         *- line following. Note: only 1st screen parameter
  5100.         *- statement is used.
  5101.         m.sect1line =  GetFirstLine("temp1","SECT","1")
  5102.         m.sect1chr = _MLINE + 2 && add CRLF
  5103.         IF sect1line # 0
  5104.             m.parmline = GetFirstLine("temp1","PARM")
  5105.             IF m.parmline # 0    && has parameter
  5106.                 *- check for continued parameter line
  5107.                 m.nCtr = 0
  5108.                 DO WHILE .T.
  5109.                     cParmLine = MLINE(temp1,parmline + m.nCtr)
  5110.                     IF RIGHT(m.cParmLine,1) # ";"
  5111.                         EXIT
  5112.                     ELSE
  5113.                         m.nCtr = m.nCtr + 1
  5114.                     ENDIF
  5115.                 ENDDO
  5116.                 m.sect1chr = _MLINE + m.nCtr + 1
  5117.             ENDIF
  5118.         ENDIF
  5119.         
  5120.         *- Get SETUP snippet SECTION 2 location
  5121.         m.sect2line =  GetFirstLine("temp1","SECT","2")
  5122.         IF m.sect2line # 0
  5123.             m.sect2chr = _MLINE + 2 && add CRLF
  5124.             m.sect2start = m.sect2chr-LEN(MLINE(temp1,m.sect2line))-2
  5125.         ENDIF
  5126.         
  5127.         DO CASE
  5128.             CASE m.sect1line = 0 AND m.sect2line = 0 AND !EMPTY(temp1)
  5129.                 *- No #SECTION directives
  5130.                 m.sect2 = temp1
  5131.             CASE m.sect1line # 0 AND m.sect2line = 0 AND m.parmline # 0
  5132.                 *- Only #SECTION1 directive, with parameter
  5133.                 m.sect1 = SUBSTR(temp1,m.sect1chr)
  5134.             CASE m.sect1line # 0 AND m.sect2line = 0
  5135.                 *- Only #SECTION1 directive, without parameter
  5136.                 m.sect1 = SUBSTR(temp1,m.sect1chr)
  5137.             OTHERWISE
  5138.                 *- Has both #SECTION1 + #SECTION2 directives
  5139.                 m.sect1 = SUBSTR(temp1,m.sect1chr,sect2start-m.sect1chr)
  5140.                 m.sect2 = SUBSTR(temp1,m.sect2chr)
  5141.         ENDCASE
  5142.  
  5143.         SELECT (m.savearea)
  5144.  
  5145.         *- Get CLEANUP snippet stuff
  5146.         *- Check for duplicate procs in platforms
  5147.         m.part2line =  GetFirstLine("PROCCODE","PROC")
  5148.         IF m.part2line = 0    && no procedures
  5149.             m.part1 = ALLTRIM(proccode)
  5150.         ELSE
  5151.             m.part2chr = _MLINE - LEN(MLINE(PROCCODE,m.part2line)) - 2
  5152.             m.part1 = SUBSTR(proccode,1,m.part2chr)
  5153.         ENDIF
  5154.  
  5155.         IF !EMPTY(m.part1)
  5156.             *- alter references to SYS(16), because they will now be in a procedure
  5157.             IF "SYS(16" $ UPPER(m.part1)
  5158.                 m.part1 = STRTRAN(m.part1,"SYS(16","_SYS(16")
  5159.                 m.part1 = STRTRAN(m.part1,"sys(16","_sys(16")
  5160.                 m.part1 = STRTRAN(m.part1,"Sys(16","_Sys(16")
  5161.                 THIS.lhasSys16 = .T.
  5162.             ENDIF
  5163.  
  5164.             *- See if Cleanup code is returning a value
  5165.             REPLACE _FOX3SPR.temp1 WITH m.part1
  5166.             SELECT _FOX3SPR
  5167.             REPLACE temp4 WITH CleanWhite(temp1)
  5168.  
  5169.             m.nmaxretu = OCCURS('RETU',m.part1)
  5170.             FOR m.j = 1 TO m.nmaxretu
  5171.                 m.ctemptxt = UPPER(MemoFind("RETU","temp4",.F.,.F.,m.j,.T.,.T.))
  5172.                 IF !EMPTY(ALLT(m.ctemptxt))
  5173.                     *- There's a return statement in there -- does anything follow it?
  5174.                     IF    ' ' $ ALLT(m.ctemptxt) AND ;
  5175.                         (UPPER(LEFT(m.ctemptxt,1)) = "R" OR ;
  5176.                         UPPER(LEFT(m.ctemptxt,2)) = "RN")
  5177.                         m.ctemptxt = SUBS(m.ctemptxt,AT(' ',m.ctemptxt) + 1)
  5178.                     ENDIF
  5179.                     *- make sure it's not just a double-ampersand comment
  5180.                     IF !EMPTY(ALLT(m.ctemptxt)) AND LEFT(ALLT(m.ctemptxt),2) != '&' + '&'
  5181.                         THIS.lHasReturn = .T.
  5182.                         EXIT
  5183.                     ENDIF
  5184.                 ENDIF
  5185.             NEXT
  5186.  
  5187.         ENDIF
  5188.  
  5189.         SELECT (m.savearea)
  5190.  
  5191.         THIS.a_reads[1] = THIS.MergeMethods(THIS.a_reads[1],m.sect1,1,m.scrn_num)
  5192.         IF !EMPTY(THIS.cParms) AND (m.scrn_num = 1 OR THIS.lMultiReads) 
  5193.             THIS.a_reads[1] = "PARAMETERS " + THIS.cParms + C_CRLF + C_CRLF + THIS.a_reads[1] 
  5194.         ENDIF
  5195.         THIS.a_reads[2] = THIS.MergeMethods(THIS.a_reads[2],m.sect2,1,m.scrn_num)
  5196.  
  5197.         IF !THIS.noReadPlainExpr AND !THIS.noReadExpr AND EMPTY(THIS.a_reads[3])
  5198.             THIS.a_reads[3] = IIF(THIS.lDevMode,"",C_CLEANUP_CODE)
  5199.         ENDIF
  5200.  
  5201.         THIS.a_reads[3] = THIS.MergeMethods(THIS.a_reads[3],m.part1,1,m.scrn_num)
  5202.         THIS.a_reads[4] = THIS.MergeMethods(THIS.a_reads[4],when,whentype,m.scrn_num)
  5203.         THIS.a_reads[5] = THIS.MergeMethods(THIS.a_reads[5],valid,validtype,m.scrn_num)
  5204.         THIS.a_reads[6] = THIS.MergeMethods(THIS.a_reads[6],show,showtype,m.scrn_num)
  5205.         THIS.a_reads[7] = THIS.MergeMethods(THIS.a_reads[7],activate,activtype,m.scrn_num)
  5206.         THIS.a_reads[8] = THIS.MergeMethods(THIS.a_reads[8],deactivate,deacttype,m.scrn_num)
  5207.     ENDPROC        &&  SCXSingleScreenConverter:AddReads
  5208.  
  5209.     *--------------------------------------
  5210.     FUNCTION MergeMethods            && SCXSingleScreenConverter
  5211.     *--------------------------------------
  5212.     PARAMETER mergeCode,fp30fld,codetype,snum
  5213.     PRIVATE m.insfile, savearea
  5214.  
  5215.         m.savearea = SELECT()
  5216.         *- codetype = 0 -> Expression
  5217.         *- codetype = 1 -> Proc
  5218.         IF EMPTY(ALLT(m.fp30fld))
  5219.           RETURN m.mergeCode
  5220.         ENDIF
  5221.         
  5222.         IF m.codetype = 0        && expression
  5223.             m.fp30fld = "RETURN "+ m.fp30fld 
  5224.         ELSE                    && procedure
  5225.             *- check for #INSERT directives
  5226.             REPLACE _FOX3SPR.temp1 WITH m.fp30fld
  5227.             SELECT _FOX3SPR
  5228.             REPLACE _FOX3SPR.temp4 WITH CleanWhite(_FOX3SPR.temp1)
  5229.  
  5230.             *- move any other #DEFINEs over
  5231.             THIS.GetDefine("temp1")
  5232.  
  5233.             THIS.FindArry
  5234.  
  5235.             DO WHILE .T.
  5236.                 m.insfile = MemoFind("#INSE","temp4",.T.,.F.,.F.,.F.,.T.)
  5237.                 IF m.insfile = C_NULL
  5238.                     EXIT
  5239.                 ENDIF
  5240.  
  5241.                 IF TYPE('m.insfile') = 'C' AND !FILE(m.insfile)
  5242.                     *- look for insert file in same dir as file we;re converting
  5243.                     IF FILE(AddBS(JustPath(THIS.cCurrentFile)) + JustFName(m.insfile))
  5244.                         m.insfile = AddBS(JustPath(THIS.cCurrentFile)) + JustFName(m.insfile)
  5245.                     ENDIF
  5246.                 ENDIF
  5247.  
  5248.                 *- check for bad file
  5249.                 DO CASE
  5250.                     CASE TYPE('m.insfile') # 'C'
  5251.                         REPLACE temp2 WITH C_INSMESS3_LOC
  5252.                     CASE EMPTY(m.insfile) OR !FILE(m.insfile) 
  5253.                         REPLACE temp2 WITH C_INSMESS3_LOC + " - " + m.insfile
  5254.                     OTHERWISE    && all is OK
  5255.                         *- add file to temporary memo
  5256.                         APPEND MEMO temp2 FROM (m.insfile) OVERWRITE
  5257.  
  5258.                         *- go through #INSERT file, and if any #DEFINEs, move them
  5259.                         *- to the .h file
  5260.                         REPLACE temp2 WITH CleanWhite(temp2)
  5261.                         THIS.GetDefine("temp2")
  5262.  
  5263.                         REPLACE temp2 WITH C_INSMESS1_LOC + m.insfile + C_CR + ;
  5264.                             temp2 + C_CR + C_INSMESS2_LOC + C_CR
  5265.                 ENDCASE
  5266.               
  5267.                 *- replace directive with specified file
  5268.                 =MemoStuff("#INSE","temp1",temp2,.T.)
  5269.                 =MemoStuff("#INSE","temp4",temp2,.T.)
  5270.  
  5271.             ENDDO
  5272.  
  5273.             m.fp30fld = temp1    && set the contents to this field
  5274.             SELECT (m.savearea)
  5275.         ENDIF
  5276.         *- m.fp30fld = "#REGION " + ALLT(STR(m.snum)) + C_CRLF + m.fp30fld
  5277.         *- Merge method code
  5278.         RETURN IIF(EMPTY(m.MergeCode),m.fp30fld,m.MergeCode + C_CRLF + m.fp30fld)
  5279.     ENDFUNC        &&  MergeMethods
  5280.  
  5281.     *------------------------------------
  5282.     PROCEDURE GetDefine            && SCXSingleScreenConverter
  5283.     *------------------------------------
  5284.     *- grab the #DEFINEs, and move to the _Fox3SPR.Defines field
  5285.     *- assume cMemoFld (name of memo) is already cleaned of leading spaces/tabs
  5286.     PARAMETER cMemoFld
  5287.  
  5288.         LOCAL gendircount, ngendir, cDefine, gendir, nCtr, cTmp, nLine
  5289.  
  5290.         IF ('#' $ &cMemoFld)
  5291.             STORE 1 TO m.gendircount
  5292.             DO WHILE .T.
  5293.                 m.ngendir = MemoFind("#",cMemoFld,.T.,.T.,m.gendircount,.T.,.T.)
  5294.                 IF m.ngendir = 0
  5295.                     EXIT
  5296.                 ENDIF
  5297.                 *-m.gendir = MLINE(&cMemoFld,1,m.ngendir - 1)
  5298.                 m.gendir = ALLT(STRTRAN(MLINE(&cMemoFld,m.ngendir),CHR(9),' '))
  5299.                 m.cDefine = ""
  5300.                 DO CASE
  5301.                     CASE UPPER(LEFT(m.gendir,5)) = "#DEFI"
  5302.                         *- check for continued #DEFINES
  5303.                         m.nCtr = 1
  5304.                         DO WHILE .T.
  5305.                             m.cDefine = m.cDefine + C_CRLF + m.gendir
  5306.                             IF RIGHT(m.gendir,1) # ";"
  5307.                                 EXIT
  5308.                             ELSE
  5309.                                 m.gendir = MLINE(&cMemoFld,m.ngendir + m.nCtr)
  5310.                                 m.nCtr = m.nCtr + 1
  5311.                             ENDIF
  5312.                         ENDDO
  5313.                         *- accumulate
  5314.                         REPLACE _FOX3SPR.defines WITH m.cDefine ADDITIVE
  5315.                     OTHERWISE
  5316.                         m.gendircount = m.gendircount + 1
  5317.                         LOOP
  5318.                 ENDCASE
  5319.                 *- Comment out directive
  5320.                 _MLINE = 0
  5321.                 nLine = MemoFind("#",cMemoFld,.T.,.T.,m.gendircount,.F.,.T.)
  5322.                 cTmp = MLINE(&cMemoFld,m.nLine - 1)                        && set _MLINE
  5323.                 REPLACE (cMemoFld) WITH STUFF(&cMemoFld,_MLINE + IIF(m.nLine <= 1,0,1),0,'*')
  5324.             ENDDO
  5325.         ENDIF
  5326.     ENDPROC        && GetDefine
  5327.  
  5328.     *------------------------------------
  5329.     PROCEDURE ScanPlat            && SCXSingleScreenConverter
  5330.     *------------------------------------
  5331.         PARAMETER cplatonly
  5332.         *- get all platforms for all screens in set
  5333.  
  5334.         PRIVATE tmparr,tmp2arr,i,j,tmpcnt,totrecs
  5335.  
  5336.         m.tmpcnt = 0
  5337.         m.totrecs = 0
  5338.  
  5339.         DIMENSION tmparr[1]
  5340.         tmparr = ""
  5341.         
  5342.         *- get total records to process for thermometer
  5343.         FOR m.i = 1 TO THIS.scxcount
  5344.             SELECT (THIS.a_scx2alias[m.i])
  5345.  
  5346.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  5347.                 *- already converted, so skip this
  5348.                 LOOP
  5349.             ENDIF
  5350.  
  5351.             IF m.cplatonly # C_All
  5352.               COUNT TO m.tmpcnt ;
  5353.                   FOR !INLIST(objtype,10,20,23) ;
  5354.                   AND platform = m.cplatonly
  5355.               ELSE
  5356.               COUNT TO m.tmpcnt ;
  5357.                   FOR !INLIST(objtype,10,20,23) ;
  5358.                   AND INLIST(platform,C_DOS,C_WINDOWS,C_MAC,C_UNIX)
  5359.             ENDIF
  5360.             m.totrecs= m.totrecs + m.tmpcnt
  5361.         ENDFOR
  5362.  
  5363.         SELECT (THIS.c25alias)
  5364.         
  5365.         FOR i = 1 TO THIS.SCXCOUNT
  5366.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  5367.                 *- already converted, so skip this
  5368.                 LOOP
  5369.             ENDIF
  5370.  
  5371.               IF m.cplatonly # C_ALL
  5372.               DIMENSION tmparr[1]
  5373.               tmparr[1] = m.cplatonly
  5374.               EXIT
  5375.             ENDIF
  5376.               SELECT DISTINCT platform;
  5377.                 FROM DBF(THIS.a_scx2alias[m.i]);
  5378.                  WHERE INLIST(platform,C_DOS,C_WINDOWS,C_MAC,C_UNIX) ;
  5379.                   INTO ARRAY tmp2arr
  5380.               
  5381.             IF EMPTY(tmparr)
  5382.                 =ACOPY(tmp2arr,tmparr)
  5383.             ELSE
  5384.                 FOR j = 1 TO ALEN(tmp2arr)
  5385.                     IF ASCAN(tmparr,ALLT(tmp2arr[m.j])) = 0
  5386.                         DIMENSION tmparr[ALEN(tmparr)+1]
  5387.                         tmparr[ALEN(tmparr)]=ALLT(tmp2arr[m.j])
  5388.                     ENDIF
  5389.                 ENDFOR
  5390.             ENDIF
  5391.             IF ALEN(tmparr) = C_MAXPLATFORMS
  5392.                 EXIT
  5393.             ENDIF
  5394.         ENDFOR
  5395.         
  5396.         *- This is for GENSCRN stuff in conprocs
  5397.         =ACOPY(tmparr,g_platforms)
  5398.         =ACOPY(tmparr,THIS.a_plat)
  5399.  
  5400.         THIS.isMultiPlat = (ALEN(tmparr) > 1)
  5401.  
  5402.         RETURN m.totrecs        
  5403.     ENDPROC        &&  ScanPlat
  5404.  
  5405.     *----------------------
  5406.     PROCEDURE AddProcs1                && SCXSingleScreenConverter
  5407.     *----------------------
  5408.         PRIVATE m.saverec,m.part2line,m.part2,m.part2chr
  5409.         m.saverec = IIF(EOF(),1,RECNO())
  5410.  
  5411.          LOCATE FOR objtype = 1 AND platform = THIS.a_plat[1]
  5412.         m.part2line =  GetFirstLine("PROCCODE","PROC")
  5413.  
  5414.         IF m.part2line = 0    && no procedures
  5415.             GO m.saverec
  5416.             RETURN
  5417.         ELSE
  5418.             *- If it's the first line, don't subtract anything
  5419.             m.part2chr = _MLINE - LEN(MLINE(proccode,m.part2line)) - IIF(m.part2line > 1,2,0)
  5420.             m.part2 = C_CRLF + SUBSTR(proccode,m.part2chr)
  5421.         ENDIF
  5422.  
  5423.          THIS.cProcs = THIS.cProcs + m.part2 + C_CRLF
  5424.  
  5425.     ENDPROC        && AddProcs1
  5426.  
  5427.     *----------------------
  5428.     PROCEDURE AddGenProcs            && SCXSingleScreenConverter
  5429.     *----------------------
  5430.         PRIVATE m.saverec,m.part2line,m.part2,m.part2chr
  5431.         m.saverec = IIF(EOF(),1,RECNO())
  5432.  
  5433.         *- add accumulated procs
  5434.         IF !EMPTY(THIS.cProcs)
  5435.             REPLACE _FOX3SPR.sprmemo WITH ;
  5436.                 C_CRLF + C_PROCS_CMMT_LOC + ;
  5437.                 THIS.cProcs + C_CRLF + ;
  5438.                 C_PROCSEND_CMMT_LOC ADDITIVE
  5439.         ENDIF
  5440.  
  5441.         *- add in stuff from VALIDs
  5442.         IF !EMPTY(_FOX3SPR.temp3)
  5443.             REPLACE _FOX3SPR.sprmemo WITH ;
  5444.                 C_CRLF + C_CRLF + C_VALID_CMMT_LOC + ;
  5445.                 _FOX3SPR.temp3 + ;
  5446.                 C_VALIDEND_CMMT_LOC ADDITIVE
  5447.         ENDIF
  5448.  
  5449.         IF THIS.lHasSys16
  5450.             *- add special function to workaround fact that SYS(16)
  5451.             *- will return something new, now that methods are buried
  5452.             *- inside forms
  5453.             REPLACE _FOX3SPR.sprmemo WITH ;
  5454.                 C_CRLF + C_CRLF + C_SYS16_CMMT_LOC + ;
  5455.                 "PROCEDURE _Sys" + C_CRLF + ;
  5456.                 C_TAB + "PARAMETERS nCode, nDepth" + C_CRLF + ;
  5457.                 C_TAB + "IF PARAMETERS() = 1" + C_CRLF + ;
  5458.                 C_TAB2 + [RETURN IIF(LEFT(SYS(16),9) == "PROCEDURE" AND OCCURS(" ",SYS(16)) >= 2,SUBS(SYS(16),AT(" ",SYS(16),2) + 1),SYS(16))] +  C_CRLF + ;
  5459.                 C_TAB + "ELSE" + C_CRLF + ;
  5460.                 C_TAB2 + "RETURN SYS(16,nDepth)" + C_CRLF + ;
  5461.                 C_TAB + "ENDIF" + C_CRLF + ;
  5462.                 C_SYS16END_CMMT_LOC ADDITIVE
  5463.         ENDIF
  5464.  
  5465.         GO    m.saverec
  5466.  
  5467.     ENDPROC        &&  AddGenProcs
  5468.  
  5469.     *----------------------------------
  5470.     PROCEDURE AddSRecs            && SCXSingleScreenConverter
  5471.     *----------------------------------
  5472.         *- Add Screen objects
  5473.         PARAMETER platnum,cRecType
  5474.         
  5475.         *- cRecType = C_DNO        environment info
  5476.         *-          = C_CONTROL    control items
  5477.         
  5478.         PRIVATE oRec, a_scx2fld
  5479.         LOCAL nOldSize
  5480.  
  5481.         SCAN FOR platform = THIS.a_plat[m.platnum]
  5482.             *- skip odd records such as WIZARD record
  5483.             IF !INLIST(PLATFORM,C_DOS,C_WINDOWS,C_MAC,C_UNIX)
  5484.                 LOOP
  5485.             ENDIF
  5486.             *- 10 group items
  5487.             IF objtype = 10
  5488.                 LOOP
  5489.             ENDIF
  5490.             
  5491.             IF (m.cRecType # C_DNO AND INLIST(objtype,2,3,4)) OR;
  5492.                 m.cRecType = C_DNO AND !INLIST(objtype,2,3,4)
  5493.                 *- environment records have already been dealt with
  5494.                 LOOP
  5495.             ENDIF
  5496.             
  5497.             SCATTER MEMO TO a_scx2fld
  5498.             
  5499.             *- Add font substitution object
  5500.             IF objtype=23
  5501.                 THIS.AddFontSub()
  5502.                 LOOP    
  5503.             ENDIF
  5504.             
  5505.             *- get control type
  5506.             oRec = THIS.AddSCXObj(objtype)
  5507.  
  5508.             IF TYPE("oRec") # "O"
  5509.                 *- some sort of problem -- couldn't create the object - 
  5510.                 *- invalid or unknown object type?
  5511.                 LOOP
  5512.             ENDIF
  5513.  
  5514.             *- map main components of 2.5 control to 3.0
  5515.             oRec.MapIt
  5516.         
  5517.             *- write out record
  5518.             oRec.AddRec
  5519.  
  5520.             *- update status bar
  5521.             gOTherm.Update(THIS.nTmpCount/THIS.nRecCount * 100)
  5522.             THIS.nTmpCount = THIS.nTmpCount + 1
  5523.             
  5524.             *- check for error and terminate early
  5525.             IF THIS.lHadError
  5526.                 THIS.CloseFiles
  5527.                 CLEAR EVENTS
  5528.                   RETURN
  5529.             ENDIF
  5530.  
  5531.             *- move any array creation references to the screen;s list of arrays
  5532.             IF !EMPTY(oRec.a_Dimes)
  5533.                 m.noldSize = ALEN(THIS.a_Dimes)
  5534.                 DIMENSION THIS.a_Dimes[m.noldSize + ALEN(oRec.a_Dimes)]
  5535.                 =ACOPY(oRec.a_Dimes, THIS.a_Dimes, 1, ALEN(oRec.a_Dimes), m.noldsize + 1)
  5536.             ENDIF
  5537.  
  5538.             *- we're done with the object, so dispose of it
  5539.             RELEASE oRec
  5540.             
  5541.         ENDSCAN
  5542.     ENDPROC        &&  SCXSingleScreenConverter:AddSRecs
  5543.  
  5544.  
  5545.     *----------------------------------
  5546.     PROCEDURE AddSCXObj            && SCXSingleScreenConverter
  5547.     *----------------------------------
  5548.         PARAMETER m.nObjType
  5549.  
  5550.         PRIVATE ctrltype,tmpobj,objclass,oForm
  5551.         STORE "" TO m.ctrltype,m.objclassm
  5552.  
  5553.         oForm = THIS.oConvForm
  5554.  
  5555.         DO CASE
  5556.             CASE m.nObjType = 1                                            && screen
  5557.                 m.ctrltype = T_FORM
  5558.                 m.objclass = THIS.formclass
  5559.             CASE m.nObjType = 2                                            && table
  5560.                 m.ctrltype = T_DATANAV
  5561.                 m.objclass = THIS.datanavclass
  5562.             CASE m.nObjType = 3                                            && index
  5563.                 THIS.lHasIDX = .T.
  5564.                 *- wd be an index -- not sure how this is to be handled...
  5565.                 REPLACE _FOX3SPR.load WITH C_SETIDX_CMMT_LOC + ;
  5566.                     "SELECT " + TRIM(a_scx2fld[A_TAG2]) + C_CR + ;
  5567.                     "SET INDEX TO " + TRIM(a_scx2fld[A_NAME])  + C_CR + C_CR ADDITIVE
  5568.             CASE m.nObjType = 4                                            && relation
  5569.                 m.ctrltype = T_RELATION
  5570.                 m.objclass = THIS.datanavRelationclass
  5571.             CASE m.nObjType = 5                                            && label
  5572.                 m.ctrltype = T_LABEL
  5573.                 m.objclass = THIS.labelclass
  5574.             CASE m.nObjType = 6                                            && line
  5575.                 m.ctrltype = T_LINE
  5576.                 m.objclass = THIS.lineclass
  5577.             CASE m.nObjType = 7                                            && box
  5578.                 m.ctrltype = T_SHAPE
  5579.                 m.objclass = THIS.shapeclass
  5580.             CASE m.nObjType = 11                                            && list
  5581.                 m.ctrltype = T_LIST
  5582.                 m.objclass = THIS.listclass
  5583.             CASE m.nObjType = 12 AND OCCUR(";",a_scx2fld[A_PICTURE])=0        && single button
  5584.                 m.ctrltype = T_BTN
  5585.                 m.objclass = THIS.btnclass
  5586.             CASE m.nObjType = 12                                            && buttongroup
  5587.                 m.ctrltype = T_BTNGRP
  5588.                 m.objclass = THIS.btngclass
  5589.             CASE m.nObjType = 13                                            && radio
  5590.                 m.ctrltype = T_RADIOGRP
  5591.                 m.objclass = THIS.radioclass
  5592.             CASE m.nObjType = 14                                            && checkbox
  5593.                 m.ctrltype = T_CBOX
  5594.                 m.objclass = THIS.cboxclass
  5595.             CASE m.nObjType = 15 AND objcode = 0                            && say
  5596.                 m.ctrltype = T_SAY
  5597.                 m.objclass = THIS.sayclass
  5598.             CASE m.nObjType = 15 AND objcode = 1                            && get
  5599.                 m.ctrltype = T_GET
  5600.                 m.objclass = THIS.getclass
  5601.             CASE m.nObjType = 15 AND objcode = 2                            && edit
  5602.                 m.ctrltype = T_EDIT
  5603.                 m.objclass = THIS.editclass
  5604.             CASE m.nObjType = 16                                            && popup
  5605.                 m.ctrltype = T_POPUP
  5606.                 m.objclass = THIS.popupclass
  5607.             CASE m.nObjType = 17 AND ;
  5608.                 (style = 0 OR (" BITMAP" $ UPPER(name))) 
  5609.                 *- ("\" $ ALLT(name)) OR ('"' $ ALLT(name)) OR (":" $ ALLT(name)) OR ;
  5610.                 *- ('.' $ ALLT(name)) OR (' ' $ ALLT(name)))    && image
  5611.                 *- assume if filename or quoted expression, it's not a GENERAL field, so not OLE!
  5612.                 m.ctrltype = T_PICT
  5613.                 objclass = THIS.pictclass
  5614.             CASE m.nObjType = 17 AND style = 1                                && ole
  5615.                 m.ctrltype = T_OLE
  5616.                 objclass = THIS.oleclass
  5617.             CASE m.nObjType = 20 AND OCCUR(";",a_scx2fld[A_PICTURE]) = 0    && invisible button
  5618.                 m.ctrltype = T_INV
  5619.                 m.objclass = THIS.invclass
  5620.             CASE m.nObjType = 20                                            && inv buttongroup
  5621.                 m.ctrltype = T_INVGRP
  5622.                 m.objclass = THIS.invgclass
  5623.             CASE m.nObjType = 22                                            && spinner
  5624.                 m.ctrltype = T_SPIN
  5625.                 m.objclass = THIS.spinclass
  5626.         ENDCASE
  5627.         
  5628.         IF EMPTY(m.ctrltype)
  5629.             RETURN ""
  5630.         ELSE
  5631.             RETURN CREATEOBJ(m.objclass,m.ctrltype,@oForm)
  5632.         ENDIF
  5633.     ENDPROC        && AddSCXObj
  5634.  
  5635.     *------------------
  5636.     PROCEDURE UpdMethods            && SCXSingleScreenConverter
  5637.     *------------------
  5638.         *- update the Formset.Readshow method after all objects have been processed
  5639.  
  5640.         LOCAL cGoTo,cCursVar,k
  5641.         cGoTo = ""
  5642.  
  5643.         SELECT (THIS.a_scx3alias[1])
  5644.  
  5645.         IF THIS.nFSetRecno > 0 AND THIS.nFSetRecno <= RECC()
  5646.             
  5647.             GO THIS.nFSetRecno
  5648.  
  5649.             IF !THIS.noReadPlainExpr
  5650.                 THIS.AddMethods(M_SETUP1,;
  5651.                     IIF(!EMPTY(THIS.a_reads[1]),THIS.a_reads[1] + C_CRLF + C_CRLF, "") + ;
  5652.                     IIF(THIS.lDevMode,"",C_SETUP_CODE) + ;
  5653.                     IIF(THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES],C_OPENTAB_CMMT_LOC + C_DATANAVLOAD + ;
  5654.                         IIF(!EMPTY(THIS.cSetSkip),C_CRLF + THIS.cSetSkip,C_CRLF) + ;
  5655.                         C_GOTO1 + ;
  5656.                         C_CRLF,"") + ;
  5657.                     THIS.cDefineWin,1)        && add #SECTION2 stuff to FORM.LOAD
  5658.                 *- clear out setup var, so it isn;t added to more than one screen in set
  5659.                 THIS.a_reads[1] = ""
  5660.                 IF THIS.lHasDataNavObj AND THIS.a_pjxsets[A_OPENFILES]
  5661.                     *- code to remember the record pointer
  5662.                     cGoTo = C_GOTO2_CMMT_LOC
  5663.                     FOR k = 1 TO ALEN(THIS.a_tables)
  5664.                         cCursVar = THIS.MakeVar(THIS.a_tables[k])
  5665.                         cGoTo = cGoTo +  C_GOTO2A + THIS.a_tables[k] + ;
  5666.                             C_GOTO2 + THIS.a_tables[k] + C_CR + ;
  5667.                             C_TAB + cCursVar + C_GOTO3 + C_CR
  5668.                     NEXT
  5669.                     THIS.a_reads[3] = cGoTo + C_CR + THIS.a_reads[3]
  5670.                 ENDIF
  5671.                 THIS.AddMethods(M_CLEANUP,THIS.a_reads[3],1)
  5672.             ENDIF
  5673.         
  5674.             *- add in the refreshed SAYs after the READ SHOW stuff already there
  5675.             THIS.cReadShow = THIS.a_reads[6] + ;
  5676.                 IIF(!EMPTY(THIS.cReadShow),C_CRLF + C_SAYSCOMMENT_LOC + C_CRLF,"") + ;
  5677.                 THIS.cReadShow
  5678.             THIS.AddMethods(M_SHOW,THIS.CleanProc(THIS.cReadShow),1)
  5679.  
  5680.             IF THIS.lDevMode
  5681.                 REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.cFormSetName + C_CRLF + THIS.fp3method ADDITIVE
  5682.             ELSE
  5683.                 REPLACE methods WITH THIS.fp3method && + C_CRLF + C_CRLF + THIS.cReadShow
  5684.             ENDIF
  5685.  
  5686.         ENDIF
  5687.     ENDPROC
  5688.  
  5689.     *------------------
  5690.     PROCEDURE MakeVar            && SCXSingleScreenConverter
  5691.     *------------------
  5692.         PARAMETER cName
  5693.         RETURN C_GOTOVARPRE + PROPER(TRIM(cName)) + C_GOTOVAREXT
  5694.     ENDPROC
  5695.     *------------------
  5696.     FUNCTION CleanProc            && SCXSingleScreenConverter
  5697.     *------------------
  5698.         *- clean out any screen directives or other stuff from snippets 
  5699.         *- that will cause problems in VFP
  5700.  
  5701.         PARAMETER cSnippet
  5702.         PRIVATE m.gendircount,savearea
  5703.         LOCAL nLine, cTmp
  5704.  
  5705.         IF !('#' $ cSnippet)
  5706.             *- if no '#', no directives, so return
  5707.             RETURN m.cSnippet
  5708.         ENDIF
  5709.  
  5710.         STORE 1 TO m.gendircount
  5711.         STORE SELECT() TO m.savearea
  5712.  
  5713.         REPLACE _FOX3SPR.temp1 WITH m.cSnippet
  5714.         REPLACE _FOX3SPR.temp4 WITH CleanWhite(_FOX3SPR.temp1)
  5715.         SELECT _FOX3SPR
  5716.  
  5717.         DO WHILE .T.
  5718.             m.gendir = UPPER(MemoFind("#","temp4",.T.,.F.,m.gendircount,.T.,.T.))
  5719.             DO CASE
  5720.                 CASE m.gendir = C_NULL
  5721.                     EXIT
  5722.                 CASE LEFT(m.gendir,4) = "NAME"
  5723.                     *- all this to comment out this code
  5724.                 OTHERWISE
  5725.                     m.gendircount = m.gendircount + 1
  5726.                     LOOP
  5727.             ENDCASE
  5728.             *- Comment out directive
  5729.             *REPLACE temp1 with STUFF(temp1,MemoFind("#","temp4",.T.,0,m.gendircount,.F.,.T.),0,'*')
  5730.             _MLINE = 0
  5731.             nLine = MemoFind("#","temp4",.T.,.T.,m.gendircount,.F.,.T.)
  5732.             cTmp = MLINE(temp1,nLine - 1)                        && set _MLINE
  5733.             REPLACE temp1 WITH STUFF(temp1,_MLINE + IIF(nLine <= 1,0,2),0,'*')
  5734.             cTmp = MLINE(temp4,nLine - 1)                        && set _MLINE
  5735.             REPLACE temp4 WITH STUFF(temp4,_MLINE + IIF(nLine <= 1,0,1),0,'*')
  5736.  
  5737.         ENDDO
  5738.  
  5739.         SELECT (m.savearea)
  5740.  
  5741.         RETURN _FOX3SPR.temp1
  5742.  
  5743.     ENDFUNC
  5744.  
  5745. ENDDEFINE    && SCXSingleScreenConverter 
  5746.  
  5747.  
  5748.  
  5749. **********************************************
  5750. DEFINE CLASS SCX30Converter AS SCXSingleScreenConverter
  5751. **********************************************
  5752.  
  5753.     lSet30Defaults = .F.
  5754.  
  5755.     *------------------------------------
  5756.     PROCEDURE Init                && SCX30Converter
  5757.     *------------------------------------
  5758.         PARAMETER aParms, lBackup, lProjCall, lForceTransportDlog, lNoCompile
  5759.  
  5760.         LOCAL cExt1, cExt2, cbackext1 , cbackext2
  5761.  
  5762.         THIS.projcall = lProjCall
  5763.  
  5764.         THIS.lBackup = m.lBackup
  5765.  
  5766.         THIS.lNoCompile = lNoCompile
  5767.  
  5768.         THIS.lSet30Defaults = (aParms[12] > 1)                    && use the check box setting
  5769.         THIS.iPlatformCount = 1
  5770.  
  5771.         IF THIS.projcall                                        && called from project
  5772.             THIS.cBackDir = gOPJX.cBackDir                        && used only for project
  5773.             DIMENSION THIS.a_scx2files[ALEN(gOPJX.a_s2files,1),3]
  5774.             DIMENSION THIS.a_scx3files[1]
  5775.             =ACOPY(gOPJX.a_s2files,THIS.a_scx2files)
  5776.             =ACOPY(gOPJX.a_s3files,THIS.a_scx3files)            
  5777.             THIS.cNewScx = THIS.a_scx3files[1]
  5778.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  5779.         ELSE
  5780.             IF EMPTY(aParms[1])
  5781.                 THIS.lUserCall = .F.    && assume called without output file
  5782.                 aParms[1] = ADDBS(JUSTPATH(aParms[4])) + LEFT(SYS(3),7) + ".SCX"
  5783.                 THIS.cNewScx = aParms[4]
  5784.             ELSE
  5785.                 THIS.cNewScx = aParms[1]
  5786.             ENDIF
  5787.             DIMENSION THIS.a_scx2files[1,3]
  5788.             THIS.a_scx2files[1,1] = aParms[4]
  5789.             THIS.a_scx2files[1,2] = ""
  5790.             THIS.a_scx2files[1,3] = aParms[4]
  5791.             THIS.cCurrentFile = THIS.a_scx2files[1,3]
  5792.             *- go ahead and make backup now, before we start
  5793.             *- if screen needs to be transported, the original is around
  5794.             cext1 = JustExt(THIS.a_scx2files[1])
  5795.             cext2 = IIF(m.cext1 == C_VCXEXT, C_VCTEXT, C_SCTEXT)
  5796.             cbackext1 = IIF(m.cext1 == C_VCXEXT, C_VCXBACKEXT, C_SCXBACKEXT)
  5797.             cbackext2 = IIF(m.cext1 == C_VCXEXT, C_VCTBACKEXT, C_SCTBACKEXT) 
  5798.             THIS.a_scx3files[1] = FORCEEXT(aParms[1],m.cext1)
  5799.             *- copy old screen with S2X,S2T extensions. No need to backup .SCR files
  5800.             IF FILE(THIS.a_scx2files[1]) AND UPPER(JUSTEXT(THIS.a_scx2files[1])) = m.cext1
  5801.                 COPY FILE (THIS.a_scx2files[1]) TO (FORCEEXT(THIS.a_scx2files[1],m.cbackext1))
  5802.             ENDIF
  5803.             IF FILE(FORCEEXT(THIS.a_scx2files[1],m.cext2))
  5804.                 COPY FILE (FORCEEXT(THIS.a_scx2files[1],m.cext2)) TO (FORCEEXT(THIS.a_scx2files[1],m.cbackext2))
  5805.             ENDIF
  5806.             *- backup has been done
  5807.             THIS.lBackUp = .F.
  5808.         ENDIF
  5809.  
  5810.         IF THIS.lSet30Defaults
  5811.             gOTherm.SetTitle(C_THERMMSG2_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  5812.             gOTherm.Update(0,"")
  5813.             gOTherm.visible = .T.
  5814.         ENDIF
  5815.  
  5816.         THIS.WriteLog("","")                    && force a blank line
  5817.         THIS.BeginLog(SYS(2027,THIS.cNewScx) )
  5818.  
  5819.         IF !THIS.KnownFile(THIS.a_scx2files[1,1])
  5820.             *- unknown file format -- error has already been written to the log
  5821.             THIS.oConvForm = .NULL.
  5822.             IF !THIS.projcall
  5823.                 *- attempt to remove backup files (jd 04/16/96)
  5824.                 THIS.EraseBackup
  5825.             ENDIF
  5826.             RETURN .F.
  5827.         ENDIF
  5828.  
  5829.         *- also check Read-Only status if project call (04/15/96 jd)
  5830.         IF THIS.projcall AND pReadOnly(THIS.cNewSCX)
  5831.             THIS.WriteLog(JUSTFNAME(THIS.cNewSCX),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  5832.             RETURN .F.
  5833.         ENDIF
  5834.  
  5835.             *- now try to open SCX file -- returns alias
  5836.             THIS.a_scx2alias[1] = THIS.OpenFile(THIS.a_scx2files[1,1])
  5837.                 
  5838.             IF EMPTY(THIS.a_scx2alias[1])
  5839.                 *- error has been logged
  5840.                 THIS.oConvForm = .NULL.
  5841.                 IF !THIS.projcall
  5842.                     *- attempt to remove backup files (jd 04/16/96)
  5843.                     THIS.EraseBackup
  5844.                 ENDIF
  5845.                 RETURN .F.
  5846.             ENDIF
  5847.  
  5848.             THIS.c25alias = THIS.a_scx2alias[1]
  5849.  
  5850.             IF FCOUNT() = C_30SCXFLDS AND FIELD(4) = "CLASS"
  5851.                 *- assume 3.0 format
  5852.                 RETURN .T.
  5853.             ELSE
  5854.                 *- error -- isn't a 3.0 SCX or VCX
  5855.                 USE IN (THIS.a_scx2alias[1])
  5856.                 THIS.WriteLog(JUSTFNAME(THIS.a_scx2files[1,1]),TRIM(E_WRONGFMT_LOC) + E_NOCONVERT_LOC)
  5857.                 THIS.oConvForm = .NULL.
  5858.                 RETURN .F.
  5859.             ENDIF
  5860.     ENDPROC
  5861.  
  5862.     *----------------------------------
  5863.     PROCEDURE Converter        && SCX30Converter
  5864.     *----------------------------------
  5865.         *- some of the defaults for VFP 4.0 have changed. So if user
  5866.         *- elected to retain the 3.0 behavior/defaults, we need to explicitly
  5867.         *- write out those properties (05/14/96 jd)
  5868.         *- this means that the checkbox is checked
  5869.         *- also need to fix colorsource property written out in a way that 4.0 can't handle
  5870.         REPLACE ALL properties WITH STRTRAN(properties,"ColorSource = 3","ColorSource = 5") ;
  5871.             FOR LOWER(baseclass) = "form"
  5872.         REPLACE ALL properties WITH STRTRAN(properties,"ColorSource = 3","ColorSource = 0") ;
  5873.             FOR LOWER(baseclass)= "line"
  5874.         IF THIS.lSet30Defaults
  5875.             THIS.Set30Defaults()
  5876.         ENDIF
  5877.         THIS.CloseFiles
  5878.         THIS.lConverted = .T.    && only set this if main screen
  5879.         RETURN
  5880.     ENDPROC
  5881.  
  5882.     *------------------------------------
  5883.     PROCEDURE CloseFiles            && SCX30Converter
  5884.     *------------------------------------
  5885.         PRIVATE i
  5886.         LOCAL cHFile, iCtr, cTmpFile, cExt1, cExt2, cbackext1 , cbackext2, cErrFile
  5887.  
  5888.         cext1 = JustExt(THIS.a_scx2files[1,3])
  5889.         cext2 = IIF(m.cext1 == C_VCXEXT, C_VCTEXT, C_SCTEXT)
  5890.         cbackext1 = IIF(m.cext1 == C_VCXEXT, C_VCXBACKEXT, C_SCXBACKEXT)
  5891.         cbackext2 = IIF(m.cext1 == C_VCXEXT, C_VCTBACKEXT, C_SCTBACKEXT) 
  5892.  
  5893.         FOR i = 1 TO ALEN(THIS.a_scx2alias)
  5894.             IF USED(THIS.a_scx2alias[m.i])
  5895.                 USE IN (THIS.a_scx2alias[m.i])
  5896.             ENDIF
  5897.         ENDFOR
  5898.  
  5899.         FOR m.i = 1 TO ALEN(THIS.a_scx3alias)
  5900.             IF USED(THIS.a_scx3alias[m.i])
  5901.                 USE IN (THIS.a_scx3alias[m.i])
  5902.             ENDIF
  5903.         ENDFOR
  5904.  
  5905.         *- if lUserCall = .T., means called via project
  5906.         *- if lUserCall = .F., means screen opened individually (also used for catalogs)
  5907.         IF !THIS.lUserCall
  5908.             IF THIS.lHadError
  5909.                 *- Delete temp files if we had an error
  5910.                 IF FILE(THIS.a_scx3files[1])
  5911.                     DELETE FILE (THIS.a_scx3files[1])
  5912.                     DELETE FILE FORCEEXT(THIS.a_scx3files[1],m.cext2)
  5913.                 ENDIF
  5914.             ELSE
  5915.                 *- Compile form
  5916.                 IF !THIS.lNoCompile
  5917.                     THIS.lLocalErr = .T.
  5918.                     IF THIS.iPlatformCount > 1 AND THIS.platform = C_MAC
  5919.                         *- use proper name for Mac specific form
  5920.                         *- converting more than one platform, and this one is Mac, so add _mac
  5921.                         *- extension to the file name
  5922.                         m.cTmpFile = (AddBS(JustPath(THIS.a_scx2files[1])) + ;
  5923.                             JustStem(THIS.a_scx2files[1]) + C_MACEXT + "." + C_SCXEXT)
  5924.                     ELSE
  5925.                         cTmpFile = THIS.a_scx2files[1]
  5926.                     ENDIF
  5927.                     cErrFile = AddBS(JustPath(m.cTmpFile)) + JustStem(m.cTmpFile) + ".ERR"
  5928.                     IF FILE(m.cErrFile)
  5929.                         ERASE (m.cErrFile)
  5930.                     ENDIF
  5931.                     IF FILE(m.cTmpFile)
  5932.                         COMPILE FORM (m.cTmpFile)
  5933.                     ENDIF
  5934.  
  5935.                     IF THIS.lHadLocErr OR FILE(m.cErrFile)
  5936.                         THIS.WriteLog(SYS(2027,THIS.cNewScx),E_NOINCLUDE_LOC)
  5937.                         =MESSAGEBOX(E_NOINCLUDE1_LOC + SYS(2027,THIS.cNewScx) + E_NOINCLUDE2_LOC)
  5938.                         THIS.lHadLocErr = .F.
  5939.                     ENDIF
  5940.                     THIS.lLocalErr = .F.
  5941.                 ENDIF
  5942.  
  5943.             ENDIF
  5944.  
  5945.         ENDIF
  5946.  
  5947.     ENDPROC        &&   SCX30Converter:CloseFiles
  5948.  
  5949. ENDDEFINE
  5950.  
  5951.  
  5952. **********************************************
  5953. DEFINE CLASS FRXConverter AS ConverterBase
  5954. **********************************************
  5955.     *- class to handle the conversion of 2.6 FRX files to 3.0 files
  5956.  
  5957.     datanavclass = "fpFRXdatanav"                        && data navigation object & cursor object
  5958.     datanavRelationClass = "fpFRXDataNavRelation"        && data navigation relation object
  5959.  
  5960.     oConvForm = .NULL.
  5961.     nObjCount = 0
  5962.     fp3prop    = ""                && properties
  5963.     nDNOCount = 0
  5964.     nDNORecNo = 0                && remember record # of DataEnvironment (nee DNO) record
  5965.     lConverted = .F.            && catch frx;s in 3.0 format
  5966.     lBackup = .F.                && backup files (as .S2X, .S2T)
  5967.     lHasDataNavObj = .F.
  5968.     projcall = .F.
  5969.     parentName = ""
  5970.     lHasInvis = .F.                && flag for if has invisible buttons
  5971.     lHasIDX    = .F.                && IDX files used in environment?
  5972.     lUserCall = .T.
  5973.     cBackDir = ""
  5974.     cNewFrx = ""                && New FRX file name
  5975.     cMainCurs = ""                && alias of main table
  5976.     lNoCompile = .F.            && flag to determine whether to compile right away, or later, in batch
  5977.  
  5978.     lNeedsDE = .T.                && need a DataEnvironment made? (transporter issue) (11/9/95 jd)
  5979.  
  5980.     cfrx2files = ""
  5981.     cfrx3files = ""
  5982.     cfrx3alias = ""
  5983.  
  5984.     DIMENSION a_scx3files[1]    && for compatibility with SCX converter
  5985.     DIMENSION a_pjxsets[10]        &&  "         "        "   "      ""
  5986.     a_pjxsets = .F.
  5987.  
  5988.     formnum = 1
  5989.  
  5990.     DIMENSION a_tables[1]        && used by datanav object
  5991.     DIMENSION a_torder[1]
  5992.     a_tables = ""
  5993.     a_torder = ""
  5994.  
  5995.     *------------------------------------
  5996.     PROCEDURE Init                && FRXConverter
  5997.     *------------------------------------
  5998.         PARAMETER aParms, lBackup, lProjCall, lForceTransportDlog, lNoCompile
  5999.  
  6000.         PRIVATE cNewFrxName, oThis
  6001.         LOCAL m.cnewext1, m.cnewext2, m.coldext1, m.coldext2
  6002.  
  6003.         THIS.oConvForm = THIS
  6004.         m.oThis = THIS
  6005.  
  6006.         THIS.projcall = lProjCall
  6007.  
  6008.         THIS.lBackup = m.lBackup
  6009.  
  6010.         THIS.lTransDlog = lForceTransportDlog
  6011.  
  6012.         THIS.lNoCompile = lNoCompile
  6013.  
  6014.         THIS.llog = aParms[9]
  6015.         THIS.cLogFile = aParms[10]
  6016.  
  6017.         THIS.lAutoOpen = .T.    && auto open tables for FRX files
  6018.         THIS.lAutoClose = .T.    && auto close tables for FRX files
  6019.         
  6020.         IF THIS.projcall                    && called from project
  6021.             THIS.cBackDir = gOPJX.cBackDir  && used only for project
  6022.             THIS.cFrx2files = gOPJX.f2files
  6023.             THIS.cFrx3files = gOPJX.f3files
  6024.             THIS.cNewFrx = THIS.cFrx3files
  6025.             THIS.cCurrentFile = THIS.cFrx3files
  6026.             IF JUSTEXT(THIS.cFrx2Files) = "LBX"
  6027.                 *- labels
  6028.                 m.coldext1 = "LBX"
  6029.                 m.coldext2 = "LBT"
  6030.                 m.cnewext1 = C_LBXBACKEXT
  6031.                 m.cnewext2 = C_LBTBACKEXT
  6032.             ELSE
  6033.                 *- reports
  6034.                 m.coldext1 = "FRX"
  6035.                 m.coldext2 = "FRT"
  6036.                 m.cnewext1 = C_FRXBACKEXT
  6037.                 m.cnewext2 = C_FRTBACKEXT
  6038.             ENDIF
  6039.         ELSE
  6040.             THIS.cNewFrx = aParms[1]
  6041.             IF EMPTY(aParms[1])
  6042.                 THIS.lUserCall = .F.    && assume called without output file
  6043.                 aParms[1] = ADDBS(JUSTPATH(aParms[4])) + "F" + RIGHT(SYS(3),7) + ".FRX"
  6044.                 THIS.cNewFrx = aParms[4]
  6045.             ENDIF
  6046.             THIS.cFrx3files = aParms[1]
  6047.             THIS.cFrx2files = aParms[4]
  6048.             THIS.cCurrentFile = THIS.cFrx2files
  6049.             IF JUSTEXT(THIS.cFrx2Files) = "LBX"
  6050.                 *- labels
  6051.                 m.coldext1 = "LBX"
  6052.                 m.coldext2 = "LBT"
  6053.                 m.cnewext1 = C_LBXBACKEXT
  6054.                 m.cnewext2 = C_LBTBACKEXT
  6055.             ELSE
  6056.                 *- reports
  6057.                 m.coldext1 = "FRX"
  6058.                 m.coldext2 = "FRT"
  6059.                 m.cnewext1 = C_FRXBACKEXT
  6060.                 m.cnewext2 = C_FRTBACKEXT
  6061.             ENDIF
  6062.             *- go ahead and make backup now, before we start
  6063.             *- this is if form needs to be transported, the original is around
  6064.             IF THIS.lBackUp
  6065.                 *- copy old form with F2X,F2T extensions
  6066.                 COPY FILE (THIS.cFrx2files) TO (FORCEEXT(THIS.cFrx2files,m.cnewext1))
  6067.                 IF FILE(FORCEEXT(THIS.cFrx2files,m.coldext2))
  6068.                     COPY FILE (FORCEEXT(THIS.cFrx2files,m.coldext2)) TO (FORCEEXT(THIS.cFrx2files,m.cnewext2))
  6069.                 ENDIF
  6070.                 *- backup has been done
  6071.                 THIS.lBackUp = .F.
  6072.             ENDIF
  6073.         ENDIF
  6074.  
  6075.  
  6076.         gOTherm.SetTitle(C_THERMMSG8_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6077.         gOTherm.Update(0,"")
  6078.         gOTherm.visible = .T.
  6079.  
  6080.         THIS.WriteLog("","")
  6081.         THIS.BeginLog(SYS(2027,THIS.cCurrentFile))
  6082.  
  6083.         THIS.platform = THIS.GetPlatForm()
  6084.         THIS.nTimeStamp = THIS.TStamp()
  6085.  
  6086.         *- also check Read-Only status if project call (04/15/96 jd)
  6087.         IF THIS.projcall AND pReadOnly(THIS.cCurrentFile)
  6088.             THIS.WriteLog(JUSTFNAME(THIS.cCurrentFile),TRIM(E_FILE_LOC) + E_NOCONVERT3_LOC)
  6089.             THIS.lHadError=.T.
  6090.             oThis = .NULL.
  6091.             RETURN .F.
  6092.         ENDIF
  6093.  
  6094.         *- now try to open FRX file -- returns alias
  6095.         *- first -- may not be a DBF (old style .FRM report), or a 1.02 FRX file
  6096.         IF FILE(THIS.cFrx2Files)
  6097.             IF Readable(THIS.cFrx2Files)
  6098.                 IF !THIS.IsDBF(THIS.cFrx2Files)
  6099.                     *- not a DBF, so try and migrate it
  6100.                     m.cNewFrxName = ForceExt(SYS(2027,THIS.cFrx2Files),;
  6101.                         IIF(UPPER(JUSTEXT(THIS.cFrx2Files)) $ "LBL|LBX",'LBX','FRX'))
  6102.                     SET MESSAGE TO C_MIGRATEMSG_LOC
  6103.                     gOTherm.SetTitle(C_THERMMSG12_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6104.                     IF !MigDB4(THIS.cFrx2Files, @oThis)
  6105.                         THIS.WriteLog(JUSTFNAME(THIS.cFrx2Files),E_NOMIG_LOC)
  6106.                         =MESSAGEBOX(E_WRONGFMT2_LOC + " " + E_NOCONVERT_LOC)
  6107.                         THIS.lHadError=.T.
  6108.                         oThis = .NULL.
  6109.                         RETURN .F.
  6110.                     ELSE
  6111.                         *- go ahead and transport
  6112.                         gOTherm.SetTitle(C_THERMMSG9_LOC + LOWER(PARTIALFNAME(THIS.cFrx2Files,C_FILELEN)))
  6113.                         gOTherm.Update(0,"")
  6114.                         LOCAL m.lOldFrxShow
  6115.                         m.lOldFrxShow = gAShowMe[N_TRANFILE_FRX,1]
  6116.                         gAShowMe[N_TRANFILE_FRX,1] = .F.
  6117.                         DO (gTransport) WITH m.cNewFrxName,13,.F.,gAShowMe, m.gOTherm,m.cNewFrxName
  6118.                         gAShowMe[N_TRANFILE_FRX,1] = m.lOldFrxShow
  6119.                         *- newly converted
  6120.                         THIS.cFrx2Files = m.cNewFrxName
  6121.                     ENDIF
  6122.                 ENDIF
  6123.             ENDIF
  6124.         ENDIF
  6125.  
  6126.         oThis = .NULL.
  6127.  
  6128.         THIS.c25alias = THIS.OpenFile(THIS.cFrx2Files)
  6129.         IF EMPTY(THIS.c25alias)
  6130.             *- error has been logged
  6131.             *- attempt to remove backup files (jd 04/16/96)
  6132.             THIS.EraseBackup
  6133.             RETURN .F.
  6134.         ENDIF
  6135.         
  6136.         *- Check for file format
  6137.         DO CASE
  6138.             CASE FCOUNT() = C_FRXFLDS AND FIELD(1) = "PLATFORM"
  6139.                 *- check for 2.5 FRX type and no platform objects
  6140.                 LOCATE FOR platform = THIS.platform
  6141.                 IF !FOUND()
  6142.                     *- =MESSAGEBOX(E_NOPLATOBJS_LOC)
  6143.                     IF !THIS.Conv20FRX(13)
  6144.                         THIS.lHadError = .T.
  6145.                         RETURN
  6146.                     ENDIF
  6147.                 ELSE
  6148.                     *- check to see if any records are later than Windows records
  6149.                     *- if so, call transporter
  6150.                     CALCULATE MAX(timestamp) FOR platform = THIS.platform TO m.imaxThisTime
  6151.                     CALCULATE MAX(timestamp) FOR platform # THIS.platform TO m.imaxOtherTime
  6152.                     IF m.imaxOtherTime > m.imaxThisTime
  6153.                         IF !THIS.Conv20FRX(13)
  6154.                             THIS.lHadError = .T.
  6155.                             RETURN
  6156.                         ENDIF
  6157.                     ENDIF
  6158.                 ENDIF
  6159.             CASE FCOUNT() = C_20FRXFLDS AND FIELD(1) = "OBJTYPE"
  6160.                 *- check for 2.0 FRX type
  6161.                 *- Invoke Transporter
  6162.                 IF !THIS.Conv20FRX(3)
  6163.                     THIS.lHadError = .T.
  6164.                     RETURN
  6165.                 ENDIF
  6166.             CASE FCOUNT() = C_30FRXFLDS AND FIELD(75) = "USER"
  6167.                 *- assume 3.0 format, report/label was already converted
  6168.                 *- (this could be called while converting a 2.x Project
  6169.                 *- that contains frx's that have already been converted)
  6170.                 *-
  6171.                 *- look to see if platform records exist for this platform
  6172.                 *- if not, we will need to transport (10/26/95 jd)
  6173.                 *-
  6174.                 LOCATE FOR platform = THIS.platform
  6175.                 IF !FOUND()
  6176.                     *- call transporter, as if it were a 2.5 file
  6177.                     THIS.Conv20FRX(13)
  6178.                     *- since no records existed from this platform, we will just use whatever
  6179.                     *- data environment stuff that was in original, and it has been transported over...
  6180.                     THIS.lNeedsDE = .F.
  6181.                     IF USED(THIS.c25alias)
  6182.                         USE IN (THIS.c25alias)
  6183.                     ENDIF
  6184.                     IF USED(THIS.cFRX3alias)
  6185.                         USE IN (THIS.cFRX3alias)
  6186.                     ENDIF
  6187.                     *- overwrite the old file with the new one
  6188.                     *- new one will be deleted later, in pjxconverter.converter
  6189.                     IF THIS.projcall
  6190.                         COPY FILE (THIS.cFRX2files) TO (FORCEEXT(THIS.cFRX3files,m.coldext1))
  6191.                         COPY FILE (FORCEEXT(THIS.cFRX2files,m.coldext2)) TO (FORCEEXT(THIS.cFRX3files,m.coldext2))
  6192.                     ENDIF
  6193.                 ELSE
  6194.                     *- check to see if any records are are later than Mac records (11/7/95 jd)
  6195.                     *-CALCULATE MAX(timestamp) FOR platform = THIS.platform TO m.imaxThisTime
  6196.                     *-CALCULATE MAX(timestamp) FOR platform # THIS.platform TO m.imaxOtherTime
  6197.  
  6198.                     *- only check header record (11/13/95 jd)
  6199.                     LOCATE FOR platform = THIS.platform AND objtype = N_OTHEADER
  6200.                     imaxThisTime = timestamp
  6201.                     LOCATE FOR platform # THIS.platform AND objtype = N_OTHEADER
  6202.                     imaxOtherTime = timestamp
  6203.  
  6204.                     IF m.imaxOtherTime > m.imaxThisTime
  6205.                         IF !THIS.Conv20FRX(13)
  6206.                             THIS.lHadError = .T.
  6207.                             RETURN
  6208.                         ENDIF
  6209.                     ENDIF
  6210.                     GO TOP
  6211.                     IF environ
  6212.                         *- has records for this platform, but check to see if there is an
  6213.                         *- environment but no DataEnvironment -- may need to make one
  6214.                         LOCATE FOR platform = THIS.platform AND objtype = N_FRX_DATAENV
  6215.                         THIS.lNeedsDE = !FOUND()
  6216.                     ENDIF
  6217.                 ENDIF
  6218.                 IF !THIS.lNeedsDE
  6219.                     THIS.lConverted = .T.
  6220.                     THIS.oConvForm = .NULL.
  6221.                     RETURN
  6222.                 ENDIF
  6223.             CASE FCOUNT() = C_20LBXFLDS AND FIELD(1) = "OBJTYPE"
  6224.                 *- assume a 2.0 LBX type
  6225.                 *- invoke transporter
  6226.                 IF !THIS.Conv20FRX(4)
  6227.                     THIS.lHadError = .T.
  6228.                     RETURN
  6229.                 ENDIF
  6230.             OTHERWISE
  6231.                 USE IN (THIS.c25alias)
  6232.                 THIS.lHadError = .T.
  6233.                 =MESSAGEBOX(E_WRONGFMT2_LOC)
  6234.                 RETURN
  6235.         ENDCASE
  6236.     
  6237.         
  6238.         *- this cursor is for working with memo fields
  6239.         IF USED("_FOX3SPR")
  6240.           USE IN _FOX3SPR
  6241.         ENDIF
  6242.  
  6243.         CREATE CURSOR _FOX3SPR (load m)
  6244.         APPEND BLANK
  6245.         SELECT (THIS.c25alias)
  6246.  
  6247.     ENDPROC        && FRXConverter:Init
  6248.  
  6249.     *----------------------------------
  6250.     PROCEDURE Converter        && FRXConverter
  6251.     *----------------------------------
  6252.         PRIVATE oRec, oForm, a_scx2fld
  6253.         LOCAL nRecCount, nCurRec, tempfile
  6254.  
  6255.         gOTherm.SetTitle(C_THERMMSG8_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6256.         gOTherm.Update(0)
  6257.  
  6258.         *- External preprocessor hook
  6259.           THIS.PreForm
  6260.  
  6261.         *- Create new FRX file here, and move records from 2.6 over
  6262.         THIS.CreateFRX
  6263.         THIS.new30alias = THIS.cFrx3Alias
  6264.  
  6265.         gOTherm.Update(33)
  6266.  
  6267.         *- the only thing we need to do is create a data environment, and take the data from the
  6268.         *- old environment records, which we left at the top of the file...
  6269.         SELECT (THIS.new30alias)
  6270.         GO TOP
  6271.         IF environ AND THIS.lNeedsDE
  6272.             *- no need to bother with this, if no environ (right?)
  6273.  
  6274.             oForm = THIS.oConvForm
  6275.  
  6276.             COUNT FOR INLIST(objtype,2,3,4) TO THIS.nRecCount
  6277.             THIS.nTmpCount = 1      && reset
  6278.  
  6279.             LOCATE FOR objtype = 2
  6280.             SCAN WHILE INLIST(objtype,2,3,4)
  6281.                 oRec = .NULL.
  6282.                 SCATTER MEMO TO a_scx2fld
  6283.                 nCurRec = RECNO()
  6284.  
  6285.                 DO CASE
  6286.                     CASE objtype = 2
  6287.                         *- table/cursor
  6288.                         oRec = CREATEOBJ(THIS.dataNavClass,T_DATANAV,@oForm)
  6289.                         oRec.fp3objtype = N_FRX_CURSOR
  6290.                     CASE objtype = 4
  6291.                         *- relation
  6292.                         oRec = CREATEOBJ(THIS.datanavRelationclass,T_RELATION,@oForm)
  6293.                         oRec.fp3objtype = N_FRX_RELATION
  6294.                     CASE objtype = 3
  6295.                         *- index
  6296.                         REPLACE _FOX3SPR.load WITH "SELECT " + TRIM(tag) + C_CR + ;
  6297.                             "SET INDEX TO " + TRIM(name)  + C_CR + C_CR ADDITIVE
  6298.                         THIS.lHasIDX = .T.
  6299.                 ENDCASE
  6300.                 IF TYPE("oRec") == "O"
  6301.                     *- created the object 
  6302.                     *- map any values
  6303.                     oRec.MapIt
  6304.                 
  6305.                     *- write out record -- but use our own device to do that, since
  6306.                     *- the DE record was done for an SCX
  6307.                     oRec.AddRec
  6308.  
  6309.                     *- check for error and terminate early
  6310.                     IF THIS.lHadError
  6311.                         THIS.CloseFiles
  6312.                         CLEAR EVENTS
  6313.                           RETURN -1
  6314.                     ENDIF
  6315.                 ENDIF
  6316.  
  6317.                 RELEASE oRec
  6318.  
  6319.                 gOTherm.Update(THIS.nTmpCount/THIS.nRecCount * 57 + 33) && account for 33 already shown, + 10 to be added in closefiles!
  6320.  
  6321.                 *- return to the record we were on
  6322.                 GO nCurRec
  6323.  
  6324.             ENDSCAN
  6325.  
  6326.             *- add in LOAD method, if IDX files were present
  6327.             IF !EMPTY(THIS.cSetSkip)
  6328.                 *- add in SET SKIP code
  6329.                 REPLACE _FOX3SPR.load WITH THIS.cSetSkip ADDITIVE
  6330.             ENDIF
  6331.  
  6332.             *- add DESTROY method
  6333.             REPLACE _FOX3SPR.load WITH C_FRXDEDESTROY ADDITIVE
  6334.  
  6335.             IF BETWEEN(THIS.nDNORecNo,1,RECC())
  6336.                 *- may say there's an environment, but no environment records are in the FRX
  6337.                 GO THIS.nDNORecNo
  6338.                 REPLACE tag WITH C_DATANAVOPEN + _FOX3SPR.load
  6339.                 IF !THIS.lNoCompile
  6340.                     THIS.CompileFRX
  6341.                 ENDIF
  6342.  
  6343.                 *- sort on platform, so dataenvironment is with other records from this platform
  6344.                 m.tempfile = ADDBS(JUSTPATH(THIS.cfrx3files)) + "F" + LEFT(SYS(3),7) +  "." + "FRX"
  6345.                 SORT ON platform TO (m.tempfile)
  6346.                 *- close the file, and replace the new FRX file with this sorted one
  6347.                 SELECT (THIS.new30alias)
  6348.                 USE
  6349.                 DELETE FILE (THIS.cfrx3files)
  6350.                 DELETE FILE (FORCEEXT(THIS.cfrx3files,IIF(JUSTEXT(THIS.cfrx3files) = "LBX","LBT","FRT")))
  6351.                 RENAME (m.tempfile) TO (THIS.cfrx3files)
  6352.                 RENAME (FORCEEXT(m.tempfile,"FRT")) TO (FORCEEXT(THIS.cfrx3files,IIF(JUSTEXT(THIS.cfrx3files) = "LBX","LBT","FRT")))
  6353.  
  6354.                 *- reopen it
  6355.                 USE  (THIS.cfrx3files)
  6356.  
  6357.             ENDIF
  6358.  
  6359.             
  6360.             RELEASE oForm
  6361.  
  6362.         ENDIF && environ
  6363.  
  6364.         *- float and stretch are different properties in VFP. Explicitly set float if stretch
  6365.         REPLACE ALL float WITH .T. FOR stretch
  6366.  
  6367.         *- External postprocessor hook
  6368.           THIS.PostForm
  6369.  
  6370.         gOTherm.Update(90)
  6371.  
  6372.         *- Close FRX files
  6373.         THIS.CloseFiles
  6374.  
  6375.         gOTherm.Complete
  6376.  
  6377.         *- write out end to log
  6378.         THIS.EndLog(THIS.cCurrentFile)
  6379.  
  6380.         RETURN THIS.cFRX2files
  6381.  
  6382.     ENDPROC
  6383.  
  6384.     *------------------------------------
  6385.     PROCEDURE CloseFiles            && FRXConverter
  6386.     *------------------------------------
  6387.         PRIVATE i, m.cnewext1, m.cnewext2, m.coldext1, m.coldext2
  6388.  
  6389.         IF JUSTEXT(THIS.cFrx2Files) = "LBX"
  6390.             *- labels
  6391.             m.coldext1 = "LBX"
  6392.             m.coldext2 = "LBT"
  6393.             m.cnewext1 = C_LBXBACKEXT
  6394.             m.cnewext2 = C_LBTBACKEXT
  6395.         ELSE
  6396.             *- reports
  6397.             m.coldext1 = "FRX"
  6398.             m.coldext2 = "FRT"
  6399.             m.cnewext1 = C_FRXBACKEXT
  6400.             m.cnewext2 = C_FRTBACKEXT
  6401.         ENDIF
  6402.  
  6403.         IF USED("_FOX3SPR")
  6404.             *- may need to move index file code over
  6405.             USE IN _FOX3SPR
  6406.         ENDIF
  6407.         
  6408.         IF USED(THIS.c25alias)
  6409.             USE IN (THIS.c25alias)
  6410.         ENDIF
  6411.  
  6412.         IF USED(THIS.cFRX3alias)
  6413.             USE IN (THIS.cFRX3alias)
  6414.         ENDIF
  6415.  
  6416.         *- Compile forms
  6417.         IF .F. AND FILE(THIS.cFRX3files)
  6418.             COMPILE FORM (THIS.cFRX3files)
  6419.         ENDIF
  6420.  
  6421.         *- if lUserCall = .T., means called via project
  6422.         *- if lUserCall = .F., means report opened individually
  6423.         *- not used with project calls.
  6424.         IF !THIS.lUserCall
  6425.             IF THIS.lHadError
  6426.                 *- Delete temp files if we had an error
  6427.                 IF FILE(THIS.cFRX3files)
  6428.                     DELETE FILE (THIS.cFRX3files)
  6429.                     DELETE FILE (FORCEEXT(THIS.cFRX3files,m.coldext2))
  6430.                 ENDIF
  6431.             ELSE
  6432.                 IF THIS.lBackUp
  6433.                     *- erase existing backup file if it;s there
  6434.                     IF FILE(FORCEEXT(THIS.cFRX2files,m.cnewext1))
  6435.                         DELETE FILE (FORCEEXT(THIS.cFRX2files,m.cnewext1))
  6436.                     ENDIF
  6437.                     IF FILE(FORCEEXT(THIS.cFRX2files,m.cnewext2))
  6438.                         DELETE FILE (FORCEEXT(THIS.cFRX2files,m.cnewext2))
  6439.                     ENDIF
  6440.                     *- Rename old screen with F2X,F2T extensions
  6441.                     RENAME (THIS.cFRX2files) TO (FORCEEXT(THIS.cFRX2files,m.cnewext1))
  6442.                     RENAME (FORCEEXT(THIS.cFRX2files,m.coldext2)) TO (FORCEEXT(THIS.cFRX2files,m.cnewext2))
  6443.                 ELSE
  6444.                     DELETE FILE (THIS.cFRX2files)
  6445.                     DELETE FILE (FORCEEXT(THIS.cFRX2files,m.coldext2))
  6446.                 ENDIF
  6447.  
  6448.                 *- Rename new FP3 report 
  6449.                 RENAME (THIS.cFRX3files) TO (THIS.cFRX2files)
  6450.                 *- temp new file is always named as an FRX file, so force FRT extension
  6451.                 RENAME (FORCEEXT(THIS.cFRX3files,"FRT")) TO (FORCEEXT(THIS.cFRX2files,m.coldext2))
  6452.             ENDIF
  6453.         ENDIF
  6454.  
  6455.     ENDPROC        &&  CloseFiles
  6456.  
  6457.     *------------------
  6458.     PROCEDURE CreateFRX            && FRXConverter
  6459.     *------------------
  6460.         *- need to add just one field
  6461.  
  6462.         SELECT (THIS.c25alias)
  6463.         COPY TO (THIS.cFRX3Files)
  6464.  
  6465.         SELECT 0
  6466.         USE (THIS.cFRX3Files)
  6467.  
  6468.         *- add the new user field
  6469.         IF TYPE("user") == 'U'
  6470.             ALTER TABLE (THIS.cFRX3Files) ADD user m
  6471.  
  6472.             *- ALTER TABLE leaves some mess behind...
  6473.             IF FILE(FORCEEXT(THIS.cFRX3Files,"BAK"))
  6474.                 DELETE FILE (FORCEEXT(THIS.cFRX3Files,"BAK"))
  6475.             ENDIF
  6476.             IF FILE(FORCEEXT(THIS.cFRX3Files,"TBK"))
  6477.                 DELETE FILE (FORCEEXT(THIS.cFRX3Files,"TBK"))
  6478.             ENDIF
  6479.  
  6480.         ENDIF
  6481.  
  6482.         *- remember the alias
  6483.         THIS.cFrx3Alias  = ALIAS()
  6484.  
  6485.     ENDPROC
  6486.  
  6487.     *------------------
  6488.     PROCEDURE Conv20FRX
  6489.     *------------------
  6490.     *- This transports an frx file
  6491.  
  6492.         PARAMETER m.frxtype
  6493.         *- m.frxtype = 13    && FP2.5 FRX format
  6494.         *- m.frxtype = 3        && FP2.0 FRX format
  6495.         *- m.frxtype = 4        && FP2.0 LBX format
  6496.         LOCAL m.oldudfp
  6497.         LOCAL m.cOldMess
  6498.  
  6499.         USE IN (THIS.c25alias)
  6500.         gOTherm.SetTitle(C_THERMMSG9_LOC + LOWER(PARTIALFNAME(THIS.cCurrentFile,C_FILELEN)))
  6501.         m.oldudfp = SET("UDFP")
  6502.         SET UDFP TO REFERENCE
  6503.         m.cOldMess = SET("MESSAGE",1)
  6504.         DO (gTransport) WITH THIS.cFrx2files,m.frxtype,.F.,gAShowMe, m.gOTherm,THIS.cCurrentFile,THIS.lTransDlog
  6505.         SET UDFP TO &oldudfp
  6506.         SET MESSAGE TO (cOldMess)
  6507.         THIS.c25alias = THIS.OpenFile(THIS.cfrx2files)
  6508.         IF !EMPTY(THIS.c25alias)
  6509.             IF (FCOUNT() = C_FRXFLDS OR FCOUNT() = C_30FRXFLDS) AND FIELD(1) = "PLATFORM"        && may be 3.0 transport, so check for 2.x + 3.0 field counts (jd 11/13/95)
  6510.                 LOCATE FOR Platform = THIS.Platform
  6511.                 IF FOUND()
  6512.                     RETURN .T.
  6513.                 ENDIF
  6514.             ENDIF
  6515.             USE IN (THIS.c25alias)
  6516.         ENDIF
  6517.         THIS.lHadError=.T.
  6518.         RETURN .F.
  6519.     ENDPROC
  6520.  
  6521.  
  6522.     *------------------
  6523.     PROCEDURE PostForm
  6524.     *------------------
  6525.         REPLACE ALL uniqueid WITH SYS(2015) FOR uniqueid = "~A" OR uniqueid = '^'
  6526.         REPLACE ALL timestamp WITH THIS.nTimeStamp FOR platform = THIS.platform
  6527.     ENDPROC
  6528.  
  6529.     *------------------------------------
  6530.     PROCEDURE Cleanup                && FRXConverter
  6531.     *------------------------------------
  6532.         *- this proc is called by Error, and tries to put things back the way they were
  6533.         *- if cleaning up from a crashed project conversion, the pjx cleanup will
  6534.         *- handle the reports
  6535.         LOCAL i
  6536.  
  6537.         IF !THIS.lUserCall 
  6538.             *- report opened individually
  6539.             *- Delete temp files if we had an error
  6540.             CLOSE TABLES
  6541.             IF FILE(THIS.cFrx3files)
  6542.                 DELETE FILE (THIS.cFrx3files)
  6543.                 IF FILE(FORCEEXT(THIS.cFrx3files,IIF(JUSTEXT(THIS.cFrx3files) = "LBX","LBT","FRT")))
  6544.                     DELETE FILE (FORCEEXT(THIS.cFrx3files,IIF(JUSTEXT(THIS.cFrx3files) = "LBX","LBT","FRT")))
  6545.                 ENDIF
  6546.             ENDIF
  6547.             IF !THIS.lBackUp
  6548.                 *- a backup could have already been made (e.g., a 2.0 file was being converted)
  6549.                 *- restore old report/label from F2X,F2T extensions
  6550.                 IF    FILE(THIS.cFrx2files) AND ;
  6551.                     FILE(FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT)) AND ;
  6552.                     FILE(FORCEEXT(THIS.cFrx2files,"FRT")) AND ;
  6553.                     FILE(FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6554.                     *- all of the files are there to attempt this, so...
  6555.                     DELETE FILE (THIS.cFrx2files)
  6556.                     DELETE FILE (FORCEEXT(THIS.cFrx2files,"FRT"))
  6557.                     IF !FILE(THIS.cFrx2files)
  6558.                         RENAME (FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT)) TO (THIS.cFrx2files)
  6559.                     ENDIF
  6560.                     IF !FILE(FORCEEXT(THIS.cFrx2files,"FRT"))
  6561.                         RENAME (FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT)) TO (FORCEEXT(THIS.cFrx2files,"FRT"))
  6562.                     ENDIF
  6563.                 ENDIF
  6564.                 *- under certain circumstances, these may be left around
  6565.                 IF FILE(FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT))
  6566.                     DELETE FILE (FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT))
  6567.                 ENDIF
  6568.                 IF FILE(FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6569.                     DELETE FILE (FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6570.                 ENDIF
  6571.             ENDIF
  6572.         ENDIF
  6573.  
  6574.         THIS.oConvForm = .NULL.
  6575.  
  6576.     ENDPROC
  6577.  
  6578.     *------------------
  6579.     PROCEDURE EraseBackup            && FRXConverter
  6580.     *------------------
  6581.         *- get rid of backup files (jd 04/15/96)
  6582.         IF FILE(FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT))
  6583.             ERASE FORCEEXT(THIS.cFrx2files,C_FRXBACKEXT)
  6584.         ENDIF
  6585.         IF FILE(FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT))
  6586.             ERASE FORCEEXT(THIS.cFrx2files,C_FRTBACKEXT)
  6587.         ENDIF
  6588.  
  6589.     ENDPROC
  6590.  
  6591.  
  6592. ENDDEFINE        && FRXConverter
  6593.  
  6594.  
  6595. **********************************************
  6596. DEFINE CLASS fp25obj AS ConverterBase
  6597. **********************************************
  6598.     
  6599.     *- Properties corresponding to new SCX form fields
  6600.     fp3plat     = ""    && platform
  6601.     fp3saveplat = C_WINDOWS        && platform that is saved in SCX file (always WINDOWS on VFP Mac --jd 03/27/96)
  6602.     fp3id         = ""    && uniqueid
  6603.     fp3time     = 0        && timestamp
  6604.     fp3comment    = ""    && comment
  6605.     fp3class    = ""    && class
  6606.     fp3base        = ""    && baseclass
  6607.     fp3name     = ""    && objname
  6608.     fp3prop        = ""    && properties
  6609.     fp3method    = ""    && methods
  6610.     fp3parent    = ""    && parent
  6611.     fp3reserved1= ""    && reserved1
  6612.     fp3reserved2= ""    && reserved2
  6613.     fp3reserved6= ""    && reserved6
  6614.  
  6615.     *- Fontmetrics
  6616.     fp3font        = ""    && font face
  6617.     fp3fsize    = ""    && font size
  6618.     fp3fstyle    = ""    && font style
  6619.     fp3font1    = 1        && FONT(TM_HEIGHT)
  6620.     fp3font5    = 0        && FONT(TM_EXTERNALLEADING)
  6621.     fp3font6    = 1     && FONT(TM_AVECHARWIDTH)
  6622.  
  6623.     fp3fudge    = 0        && fudge factor for horizontal positioning
  6624.  
  6625.     *- Object Code 
  6626.     fp25OT = 0
  6627.     fp25OC = 0
  6628.     
  6629.     *- Object References
  6630.     formRef = ""
  6631.     
  6632.     *- Picture clause parts (ex. "@KJ XXXXX")
  6633.     *- ex. picword1 = @KJ  
  6634.     *-     picword2 = XXXXX
  6635.     
  6636.     picword1 = ""
  6637.     picword2 = ""
  6638.     picword3 = ""
  6639.     hasitse  = .F.
  6640.     
  6641.     iColorSource = I_DEFCOLORSOURCE
  6642.     
  6643.     *----------------------
  6644.     PROCEDURE Init            && fp25obj
  6645.     *----------------------
  6646.         PARAMETER parm1,parm2
  6647.         THIS.fp3class  = m.parm1            && class
  6648.         THIS.fp3base   = m.parm1            && baseclass
  6649.         THIS.formRef   = m.parm2            && form reference
  6650.         THIS.fp25OT    = a_scx2fld[A_ObjType]
  6651.         THIS.fp25OC    = a_scx2fld[A_ObjCode]
  6652.         THIS.fp3prop   = ""                    && properties
  6653.         THIS.fp3method = ""                    && methods
  6654.     ENDPROC
  6655.  
  6656.     *----------------------
  6657.     PROCEDURE MapIt
  6658.     *----------------------
  6659.         *- This is the main mapping program.
  6660.         *- It uses FP25OBJ base methods unless
  6661.         *- overridden by subclass method.
  6662.         THIS.PreMap
  6663.         THIS.AddBasic
  6664.         THIS.AddFont
  6665.         THIS.AddPos
  6666.         THIS.AddColor
  6667.         THIS.AddMain
  6668.         THIS.PostMap
  6669.         THIS.WriteName     && note Name property must be written last!
  6670.     ENDPROC
  6671.  
  6672.     *----------------------
  6673.     PROCEDURE AddMain
  6674.     *----------------------
  6675.     ENDPROC
  6676.     
  6677.     *----------------------
  6678.     PROCEDURE PreMap
  6679.     *----------------------
  6680.     ENDPROC
  6681.     
  6682.     *----------------------
  6683.     PROCEDURE PostMap
  6684.     *----------------------
  6685.     ENDPROC
  6686.  
  6687.     *----------------------
  6688.     FUNCTION FullBMP
  6689.     *----------------------
  6690.         *- returns fullpath of BMP
  6691.         PARAMETER bmpfpath
  6692.         RETURN bmpfpath
  6693.         
  6694.     ENDFUNC
  6695.  
  6696.     *----------------------
  6697.     FUNCTION GetPicPart
  6698.     *----------------------
  6699.         PARAMETER cPictStr
  6700.         *- picword1 (format)
  6701.         *- picword2 (inputmsk,bmp,caption)
  6702.         *- picword3 (misc #ITSE add-ons)
  6703.         
  6704.         PRIVATE spcloc,tmpstr,tmpcnt,tmpword,tmploc,tmpprestr
  6705.         IF EMPTY(ALLTRIM(m.cPictStr))
  6706.             RETURN
  6707.         ENDIF
  6708.         
  6709.         m.cPictStr = SUBS(m.cPictStr,2,LEN(m.cPictStr) - 2)    && EVAL(m.cPictStr)    && remove dbl quotes
  6710.         
  6711.         *- check for #ITSEXPRESSION
  6712.         IF !EMPTY(THIS.formRef.itse_expr) AND ;
  6713.             INLIST(a_scx2fld[A_ObjType],15,22) AND ;
  6714.             AT(THIS.formRef.itse_expr,m.cPictStr) # 0
  6715.             *- parse out GENSCRN tricks
  6716.             *- ex.   ~ [] NOMODIFY 
  6717.             *-       ~ [@!] COLOR ,N/N
  6718.             THIS.hasitse = .T.
  6719.             m.tmploc = AT(THIS.formRef.itse_expr,m.cPictStr)
  6720.             m.tmpstr = ALLT(SUBSTR(m.cPictStr,m.tmploc + 1))
  6721.             m.tmpprestr = LEFT(m.cPictStr,m.tmploc - 1)
  6722.             m.tmpcnt = 1
  6723.             DO WHILE .T.
  6724.                 tmpword = WORDNUM(m.tmpstr,m.tmpcnt)
  6725.                 DO CASE
  6726.                     CASE EMPTY(m.tmpword)
  6727.                         EXIT
  6728.                     CASE UPPER(m.tmpword) $ "NOMODIFY FONT STYLE COLOR SIZE"
  6729.                         THIS.picword3 = SUBSTR(m.tmpstr,AT(m.tmpword,m.tmpstr))
  6730.                         m.tmpstr = RTRIM(LEFT(m.tmpstr,AT(m.tmpword,m.tmpstr)-1))                 
  6731.                         EXIT
  6732.                 ENDCASE
  6733.                 m.tmpcnt = m.tmpcnt+1
  6734.             ENDDO
  6735.             IF EMPTY(m.tmpprestr)
  6736.                 m.cPictStr = m.tmpstr
  6737.             ENDIF
  6738.         ENDIF
  6739.         
  6740.         *- get location of space
  6741.         spcloc = ATC(" ",m.cPictStr)
  6742.         
  6743.         DO CASE
  6744.             CASE THIS.hasitse AND !EMPTY(m.tmpprestr)
  6745.                 THIS.picword1 = THIS.addquotes(ALLTRIM(m.tmpprestr))
  6746.                 THIS.picword2 = ALLTRIM(m.tmpstr)
  6747.             CASE THIS.hasitse AND AT("@",m.cPictStr)=0
  6748.                 THIS.picword2 = m.cPictStr
  6749.             CASE THIS.hasitse
  6750.                 THIS.picword1 = m.cPictStr
  6751.             CASE m.spcloc = 0 AND AT("@",m.cPictStr) # 0
  6752.                 THIS.picword1 = m.cPictStr
  6753.             CASE m.spcloc = 0
  6754.                 THIS.picword2 = m.cPictStr
  6755.             CASE AT("@",m.cPictStr) = 0
  6756.                 THIS.picword2 = m.cPictStr
  6757.             CASE EMPTY(SUBSTR(m.cPictStr,m.spcloc))
  6758.                 THIS.picword1 = m.cPictStr
  6759.             OTHERWISE
  6760.                 THIS.picword1 = LEFT(m.cPictStr,m.spcloc-1)
  6761.                 THIS.picword2 = ALLT(SUBSTR(m.cPictStr,m.spcloc+1))
  6762.         ENDCASE
  6763.         
  6764.         IF THIS.hasitse
  6765.             * special handling for #ITSEXPRESSION
  6766.             IF !EMPTY(THIS.picword1) AND EMPTY(m.tmpprestr) AND ;
  6767.                 LEFT(LTRIM(THIS.picword1),1) # "+"
  6768.                 THIS.picword1 = "+" + THIS.picword1
  6769.             ENDIF
  6770.             
  6771.             IF !EMPTY(THIS.picword2) AND ;
  6772.                 LEFT(LTRIM(THIS.picword2),1) # "+"
  6773.                 THIS.picword2 = "+" + THIS.picword2
  6774.             ENDIF        
  6775.         ENDIF
  6776.     ENDFUNC
  6777.     
  6778.     *----------------------
  6779.     PROCEDURE AddRec        && fp25obj
  6780.     *----------------------
  6781.         *- Add record to FORM file
  6782.         *- NOTE: This is overridden in some cases (e.g. fp25form)
  6783.         *- where different value needs to be inserted into reserved4 field
  6784.         IF THIS.formRef.lDevMode
  6785.             *- put methods someplace else
  6786.             INSERT INTO (THIS.formRef.new30alias) ;
  6787.              (platform,uniqueid,timestamp,;
  6788.               class,baseclass,objname,parent,properties,;
  6789.               user,reserved2);
  6790.              VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  6791.               THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  6792.               THIS.fp3parent,THIS.fp3prop,;
  6793.               THIS.fp3comment,;
  6794.               THIS.fp3reserved2)
  6795.             IF !EMPTY(THIS.fp3method)
  6796.                 REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.fp3name + C_CRLF + THIS.fp3method ADDITIVE
  6797.             ENDIF
  6798.         ELSE
  6799.             INSERT INTO (THIS.formRef.new30alias) ;
  6800.              (platform,uniqueid,timestamp,;
  6801.               class,baseclass,objname,parent,properties,;
  6802.               methods,user,reserved2);
  6803.              VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  6804.               THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  6805.               THIS.fp3parent,THIS.fp3prop,;
  6806.               THIS.fp3method,;
  6807.               THIS.fp3comment,;
  6808.               THIS.fp3reserved2)
  6809.         ENDIF
  6810.     ENDPROC
  6811.  
  6812.     *----------------------
  6813.     PROCEDURE AddBasic        && fp25obj
  6814.     *----------------------
  6815.         *- Update common fields
  6816.         THIS.fp3plat     = a_scx2fld[A_PLATFORM]         && platform
  6817.         THIS.fp3time     = THIS.formRef.nTimeStamp     && timestamp
  6818.         THIS.fp3comment    = a_scx2fld[A_COMMENT]        && comment
  6819.         THIS.fp3parent  = THIS.formRef.parentName
  6820.         THIS.fp3id         = "~A"                         && we'll sort on this field later
  6821.         THIS.formRef.lHasInvis = .T.
  6822.     ENDPROC
  6823.  
  6824.     *----------------------
  6825.     PROCEDURE AddName    && fp25obj
  6826.     *----------------------
  6827.         PARAMETER cAddname
  6828.         THIS.fp3name = m.cAddname
  6829.     ENDPROC
  6830.  
  6831.     *----------------------
  6832.     PROCEDURE WriteName    && fp25obj
  6833.     *----------------------
  6834.         THIS.AddProp(M_NAME,THIS.fp3name)
  6835.     ENDPROC
  6836.  
  6837.     *----------------------
  6838.     PROCEDURE AddFont    && fp25obj
  6839.     *----------------------
  6840.         PARAMETER m.nbtn
  6841.         
  6842.         *- check for non-GUI platform
  6843.         IF !INLIST(a_scx2fld[A_PLATFORM],C_MAC,C_WINDOWS)
  6844.             RETURN
  6845.         ENDIF
  6846.     
  6847.         THIS.fp3font  = ALLTRIM(a_scx2fld[A_FONTFACE])
  6848.         THIS.fp3fsize = a_scx2fld[A_FONTSIZE]
  6849.         THIS.fp3fstyle = THIS.GetStyle(a_scx2fld[A_FONTSTYLE])
  6850.         
  6851.         THIS.fp3font1 = FONT(1,THIS.fp3font,THIS.fp3fsize,THIS.fp3fstyle)
  6852.         THIS.fp3font5 = FONT(5,THIS.fp3font,THIS.fp3fsize,THIS.fp3fstyle)
  6853.         THIS.fp3font6 = FONT(6,THIS.fp3font,THIS.fp3fsize,THIS.fp3fstyle)
  6854.         
  6855.         THIS.nDeffont1 = THIS.formRef.nDeffont1     && default screen font1
  6856.         THIS.nDeffont5 = THIS.formRef.nDeffont5     && default screen font5
  6857.         THIS.nDeffont6 = THIS.formRef.nDeffont6     && default screen font6
  6858.  
  6859.         *- Add fontface and fontsize
  6860.         THIS.AddProp(M_FONTFACE,THIS.fp3font,m.nbtn)
  6861.         THIS.AddProp(M_FONTSIZE,THIS.fp3fsize,m.nbtn)
  6862.         
  6863.         *- Add font styles
  6864.         
  6865.         *- Bold is default on some so always add it
  6866.         THIS.AddProp(M_FONTBOLD,ATC("B",THIS.fp3fstyle) # 0,m.nbtn)
  6867.         
  6868.         *- Italic
  6869.         IF ATC("I",THIS.fp3fstyle) # 0 
  6870.             THIS.AddProp(M_FONTITAL,C_TRUE,m.nbtn)
  6871.         ENDIF
  6872.         
  6873.         *- Underline
  6874.         IF ATC("U",THIS.fp3fstyle) # 0 
  6875.             THIS.AddProp(M_FONTUNDER,C_TRUE,m.nbtn)
  6876.         ENDIF
  6877.  
  6878.         IF _mac
  6879.             *- these attributes only exist on the Mac (12/5/95 jd)
  6880.             IF ATC("O",THIS.fp3fstyle) # 0 
  6881.                 THIS.AddProp(M_FONTOUTLINE,C_TRUE,m.nbtn)
  6882.             ENDIF
  6883.  
  6884.             *- these attributes only exist on the Mac (12/5/95 jd)
  6885.             IF ATC("S",THIS.fp3fstyle) # 0 
  6886.                 THIS.AddProp(M_FONTSHADOW,C_TRUE,m.nbtn)
  6887.             ENDIF
  6888.  
  6889.             *- these attributes only exist on the Mac (12/5/95 jd)
  6890.             IF ATC("C",THIS.fp3fstyle) # 0 
  6891.                 THIS.AddProp(M_FONTCONDENSE,C_TRUE,m.nbtn)
  6892.             ENDIF
  6893.  
  6894.             *- these attributes only exist on the Mac (12/5/95 jd)
  6895.             IF ATC("E",THIS.fp3fstyle) # 0 
  6896.                 THIS.AddProp(M_FONTEXTEND,C_TRUE,m.nbtn)
  6897.             ENDIF
  6898.  
  6899.         ENDIF
  6900.  
  6901.     ENDPROC
  6902.     
  6903.     *----------------------
  6904.     PROCEDURE AddPos        && fp25obj
  6905.     *----------------------
  6906.         *- Add object positions in pixels (how FP3 stores it)
  6907.         *- VPOS,HPOS based on form font
  6908.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * (THIS.nDeffont1+THIS.nDeffont5))        
  6909.         THIS.AddProp(M_HPOS,(a_scx2fld[A_HPOS] - THIS.fp3fudge) * THIS.nDeffont6)
  6910.         
  6911.         *- HEIGHT,WIDTH based on object font
  6912.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  6913.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  6914.             (THIS.fp3font1+THIS.fp3font5))
  6915.  
  6916.     ENDPROC
  6917.  
  6918.     *----------------------
  6919.     PROCEDURE AddColor    && fp25obj
  6920.     *----------------------
  6921.         *- Add colorstuff
  6922.         *- Add pen color
  6923.         PARAMETER m.btn
  6924.  
  6925.         THIS.AddProp(M_COLORSOURCE, THIS.iColorSource, m.btn)        && made colorsource value a property, so it is easier too override (jd 06/20/96)
  6926.  
  6927.         IF a_scx2fld[A_PENRED] # -1
  6928.             
  6929.             THIS.AddProp(M_PEN,ALLT(STR(a_scx2fld[A_PENRED])) + ;
  6930.                 "," + ALLT(STR(a_scx2fld[A_PENGREEN])) + ;
  6931.                 "," + ALLT(STR(a_scx2fld[A_PENBLUE])),m.btn)
  6932.  
  6933.         ENDIF
  6934.         
  6935.         *- Add fill color
  6936.         IF a_scx2fld[A_FILLRED] = -1
  6937.         ELSE                
  6938.             THIS.AddProp(M_BACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  6939.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  6940.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])),m.btn)
  6941.             THIS.AddProp(M_FILLCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  6942.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  6943.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])),m.btn)
  6944.             THIS.AddProp(M_DISBACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  6945.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  6946.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])),m.btn)
  6947.         ENDIF
  6948.     ENDPROC            && fp25obj
  6949.     
  6950.     *----------------------
  6951.     FUNCTION GetStyle    && fp25obj
  6952.     *----------------------
  6953.         *- Takes font style in SCX/FRX file and converts to
  6954.         *- font style code used by FONTMETRIC functions.
  6955.         PARAMETER iFntStyle
  6956.         LOCAL cFontStyle, i
  6957.         cFontStyle = "N"
  6958.         m.cStyleCodes = "BIUOSCE"   && bold (1), italic (2), underline (4), outline (8), 
  6959.                                     && shadow (16), condensed (32), extended (64)
  6960.  
  6961.         IF m.iFntStyle > 0
  6962.             *- has an attribute
  6963.             FOR i = 6 TO 0 STEP -1
  6964.                 IF m.iFntStyle >= 2^i
  6965.                     m.cFontStyle = m.cFontStyle + SUBSTR(m.cStyleCodes,i + 1,1)
  6966.                     m.iFntStyle = m.iFntStyle - 2^i
  6967.                 ENDIF
  6968.             NEXT 
  6969.         ENDIF
  6970.  
  6971.         RETURN m.cFontStyle
  6972.  
  6973.         *DO CASE
  6974.         *    CASE m.iFntStyle = 1        && BOLD
  6975.         *        RETURN 'B'
  6976.         *    CASE m.iFntStyle = 2        && ITALIC
  6977.         *        RETURN 'I'
  6978.         *    CASE m.iFntStyle = 3        && BOLD ITALIC
  6979.         *        RETURN 'BI'
  6980.         *    OTHERWISE                      && NORMAL
  6981.         *        RETURN 'N'
  6982.         *ENDCASE
  6983.     ENDFUNC 
  6984.     
  6985.     *----------------------
  6986.     FUNCTION GetNewName    && fp25obj
  6987.     *----------------------
  6988.         PARAMETER newobj
  6989.         PRIVATE cName
  6990.  
  6991.         cName = ALLT(a_scx2fld[A_NAME]) 
  6992.         *- use data source if available
  6993.         IF !EMPTY(cName)
  6994.             *- name could be an array element, so strip out
  6995.             m.cName = CHRTRANC(m.cName,",()[]","_")
  6996.             IF " " $ cName
  6997.                 *- space in name (e.g. "varname BITMAP") -- 
  6998.                 *- for now, take everything up to it
  6999.                 cName = LEFT(cName, AT(" ",cName) - 1)
  7000.                 IF ("\" $ cName) OR ("." $ cName) OR (":" $ cName)
  7001.                     *- assume is some kind of filename
  7002.                     *- strip off quotes if they are there
  7003.                     m.cName = JustStem(StripQuote(m.cname))
  7004.                 ENDIF
  7005.             ELSE
  7006.                 m.cName = IIF("->" $ cName,SUBSTR(cName,AT("->",cName) + 2),;
  7007.                         SUBSTR(cName,AT(".",cName) + 1))
  7008.             ENDIF
  7009.         ELSE
  7010.             m.cName = m.newobj
  7011.         ENDIF
  7012.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  7013.         RETURN THIS.GetVarPrefix(m.newobj) + PROPER(ALLTRIM(m.cName)) + ALLTRIM(STR(THIS.formRef.nObjCount))
  7014.     ENDFUNC        &&  GetNewName
  7015.  
  7016.     *----------------------
  7017.     PROCEDURE AddFormat        && fp25obj
  7018.     *----------------------
  7019.         *- Add function codes - format
  7020.         DO CASE 
  7021.             CASE EMPTY(THIS.picword1)
  7022.                 *- skip
  7023.             CASE !THIS.hasitse
  7024.                 THIS.AddProp(M_FORMAT,THIS.addquotes(THIS.picword1))
  7025.             OTHERWISE
  7026.                 THIS.AddProp(M_FORMAT,THIS.picword1)
  7027.         ENDCASE
  7028.         
  7029.         *- Add picture codes - inputmask
  7030.         DO CASE
  7031.             CASE EMPTY(THIS.picword2)
  7032.             CASE !THIS.hasitse 
  7033.                 THIS.AddProp(M_INPUTMSK,THIS.addquotes(THIS.picword2))
  7034.             OTHERWISE
  7035.                 THIS.AddProp(M_INPUTMSK,THIS.picword2)
  7036.         ENDCASE
  7037.     ENDPROC        &&  AddFormat
  7038.     
  7039.     *----------------------
  7040.     PROCEDURE AddFX        && fp25obj
  7041.     *----------------------
  7042.         *- Add Special Effects
  7043.         *- support 3-D effects from FoxMac 2.6 (12/5/95 jd)
  7044.         PARAMETER btn
  7045.         IF a_scx2fld[A_PLATFORM] = C_MAC AND "3" $ THIS.picword1
  7046.             THIS.AddProp(M_SPECIAL,N_3D,m.btn)
  7047.         ELSE
  7048.             THIS.AddProp(M_SPECIAL,N_PLAIN,m.btn)
  7049.         ENDIF
  7050.     ENDPROC
  7051.  
  7052.     *----------------------
  7053.     PROCEDURE AddMode        && fp25obj
  7054.     *----------------------
  7055.         *- add the mode (opaque/transparent)
  7056.         *- if mode has to be converted, check for opaque w/ no fill pat
  7057.         PARAMETER lConvert,nMode,nFillPat,m.btn
  7058.         IF !lConvert
  7059.             THIS.AddProp(M_MODE,nMode,m.btn)
  7060.         ELSE
  7061.             *- reverse transparent/opaque value in 3.0
  7062.             THIS.AddProp(M_MODE,ABS(nMode - 1),m.btn)
  7063.         ENDIF
  7064.     ENDPROC
  7065.  
  7066.     *----------------------
  7067.     PROCEDURE Conv2Str
  7068.     *----------------------
  7069.         PARAMETER pstring
  7070.         DO CASE
  7071.         CASE TYPE(m.pstring) = "L"
  7072.             RETURN "IIF("+m.pstring+",'T','F')"
  7073.         CASE INLIST(TYPE(m.pstring),"N","F")
  7074.             RETURN "ALLTRIM(STR("+m.pstring+"))"
  7075.         CASE TYPE(m.pstring) = "D"
  7076.             RETURN "DTOS("+m.pstring+")"
  7077.         OTHERWISE      && don't index
  7078.             RETURN m.pstring
  7079.         ENDCASE
  7080.     ENDPROC
  7081.  
  7082. ENDDEFINE        &&  fp25obj 
  7083.  
  7084.  
  7085. ************************************
  7086. DEFINE CLASS fp25ctrl AS fp25obj
  7087. ************************************
  7088.         
  7089.     *----------------------
  7090.     PROCEDURE AddBasic        && fp25ctrl
  7091.     *----------------------
  7092.         fp25obj::AddBasic
  7093.         THIS.fp3id = "~B"        && we'll sort on this field later
  7094.     ENDPROC
  7095.  
  7096.     *----------------------
  7097.     PROCEDURE AddMain        && fp25ctrl
  7098.     *----------------------
  7099.         *- Now add control specific properties
  7100.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  7101.         
  7102.         *- add mode
  7103.         THIS.AddMode(L_CONVERT,a_scx2fld[A_MODE],a_scx2fld[A_FILLPAT])
  7104.  
  7105.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_WHENTYPE] == 0)
  7106.             THIS.AddMethods(M_WHEN2,THIS.FormRef.CleanProc(a_scx2fld[A_WHEN]),a_scx2fld[A_WHENTYPE])
  7107.         ENDIF
  7108.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_VALIDTYPE] == 0)
  7109.             THIS.AddMethods(M_VALID2,THIS.FormRef.CleanProc(a_scx2fld[A_VALID]),a_scx2fld[A_VALIDTYPE])
  7110.         ENDIF
  7111.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_MESSTYPE] == 0)
  7112.             THIS.AddMethods(M_MESSAGE,a_scx2fld[A_MESSAGE],a_scx2fld[A_MESSTYPE])
  7113.         ENDIF
  7114.         IF !THIS.formref.noReadPlainExpr OR (a_scx2fld[A_ERRORTYPE] == 0)
  7115.             THIS.AddMethods(M_ERROR,a_scx2fld[A_ERROR],a_scx2fld[A_ERRORTYPE])
  7116.         ENDIF
  7117.         IF !THIS.formRef.lHasSys16
  7118.             THIS.formRef.lHasSys16 = ("SYS(16" $ UPPER(THIS.fp3method))
  7119.         ENDIF
  7120.  
  7121.         *- Get parts of Picture clause for use below
  7122.         THIS.GetPicPart(a_scx2fld[A_PICTURE])
  7123.  
  7124.         *- add releaseerase
  7125.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  7126.  
  7127.         *- DO specific action for control
  7128.         THIS.AddCtrl
  7129.  
  7130.         *- Add datasource (field, memvar, etc.)
  7131.         *- This has to be added after Value, RowSource etc,
  7132.         THIS.AddProp(M_DATASOURCE,ALLTRIM(a_scx2fld[A_NAME]))
  7133.  
  7134.         *- add 3D special effects
  7135.         THIS.AddFX
  7136.  
  7137.  
  7138.     ENDPROC    && AddMain
  7139.     
  7140.     *----------------------
  7141.     PROCEDURE AddCtrl        && fp25ctrl
  7142.     *----------------------
  7143.                 
  7144.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7145.  
  7146.     ENDPROC
  7147.     
  7148.     *----------------------
  7149.     PROCEDURE AddGroup        && fp25ctrl
  7150.     *----------------------
  7151.         PARAMETER btnname,invisbtn,optbtn
  7152.         
  7153.         PRIVATE i,capname,btn,vspc,hspc,lhaspicts,totbtns
  7154.         PRIVATE unitwid,unithgt,st_left,st_top,lishoriz
  7155.                 
  7156.         m.totbtns = OCCUR(";",a_scx2fld[A_PICTURE]) + 1
  7157.         m.lhaspicts = ATC("B",THIS.picword1) # 0
  7158.         m.lishoriz =  ATC("H",THIS.picword1) # 0
  7159.  
  7160.         *- VPOS,HPOS based on form font
  7161.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * (THIS.nDeffont1 + THIS.nDeffont5))        
  7162.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS] * THIS.nDeffont6)
  7163.  
  7164.         IF m.lishoriz  && horizontal buttons
  7165.             THIS.AddProp(M_WIDTH,((a_scx2fld[A_WIDTH]+a_scx2fld[A_SPACING]) * ;
  7166.                 m.totbtns*THIS.fp3font6)-(a_scx2fld[A_SPACING]*THIS.fp3font6))
  7167.             THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7168.                 (THIS.fp3font1+THIS.fp3font5))
  7169.             m.vspc = 0
  7170.             m.hspc = a_scx2fld[A_SPACING]*THIS.fp3font6
  7171.         ELSE
  7172.             THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  7173.             THIS.AddProp(M_HEIGHT,((a_scx2fld[A_HEIGHT] + a_scx2fld[A_SPACING]) * ;
  7174.                 m.totbtns * (THIS.fp3font1 + THIS.fp3font5)) - ;
  7175.                 (a_scx2fld[A_SPACING] * (THIS.fp3font1 + THIS.fp3font5)))
  7176.             m.vspc = a_scx2fld[A_SPACING] * (THIS.fp3font1 + THIS.fp3font5)
  7177.             m.hspc = 0
  7178.         ENDIF
  7179.  
  7180.         IF m.btnName = "Option"
  7181.             THIS.AddMode(L_NOCONVERT,0)      && always transparent
  7182.         ELSE
  7183.             THIS.AddMode(L_NOCONVERT,0)      && always transparent
  7184.         ENDIF
  7185.  
  7186.         THIS.AddProp(M_BORDER,0)            && no auto-border around group
  7187.  
  7188.         THIS.AddProp(M_BUTTONS,m.totbtns)    && number of buttons
  7189.         
  7190.         m.unitwid = a_scx2fld[A_WIDTH] * THIS.fp3font6
  7191.         m.unithgt = a_scx2fld[A_HEIGHT] * (THIS.fp3font1 + THIS.fp3font5)
  7192.  
  7193.         *- buttons are offset from their container
  7194.         m.st_top = 0
  7195.         m.st_left = 0        
  7196.  
  7197.         *- Add name here - must be last
  7198.         THIS.AddProp(M_NAME,THIS.fp3name)
  7199.         
  7200.         *- Add specific buttons detail
  7201.         FOR i = 1 TO m.totbtns 
  7202.             m.btn = m.btnname + ALLTRIM(STR(m.i))
  7203.             DO CASE
  7204.                 CASE m.totbtns = 1    && single button
  7205.                     m.capname = THIS.picword2    
  7206.                 CASE m.i = 1
  7207.                     m.capname = LEFT(THIS.picword2,AT(";",THIS.picword2)-1)
  7208.                 CASE m.i = m.totbtns
  7209.                     m.capname = SUBSTR(THIS.picword2,RAT(";",THIS.picword2)+1)
  7210.                 OTHERWISE
  7211.                     m.pos1 = AT(";",THIS.picword2,m.i-1)+1
  7212.                     m.pos2 = AT(";",THIS.picword2,m.i)
  7213.                     m.capname = SUBSTR(THIS.picword2,m.pos1,m.pos2-m.pos1)                
  7214.             ENDCASE
  7215.             
  7216.             *- individual buttons have font attributes
  7217.             THIS.AddFont(m.btn)
  7218.  
  7219.             *- individual buttons need color props set
  7220.             THIS.AddColor(m.btn)
  7221.  
  7222.             *- make plain
  7223.             THIS.AddFX(m.btn)
  7224.             *- THIS.AddProp(M_SPECIAL,N_PLAIN,m.btn)
  7225.  
  7226.             DO CASE
  7227.                 CASE m.invisbtn            && invisible buttons
  7228.                     THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED],m.btn)
  7229.                     THIS.AddProp(M_STYLE,1,m.btn)
  7230.                 CASE m.lhaspicts         && picture buttons
  7231.                     THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED],m.btn)
  7232.                     THIS.AddProp(M_FPICTURE,THIS.FullBMP(m.capname),m.btn)
  7233.                     THIS.AddProp(M_CAPTION,[""],m.btn)
  7234.                     IF m.optbtn
  7235.                         THIS.AddProp(M_STYLE,1,m.btn)
  7236.                     ENDIF
  7237.                 OTHERWISE
  7238.                     IF "\\" $ m.capname
  7239.                         *- disabled, so strip out double backslash
  7240.                         m.capname = STRTRAN(m.capname,"\\")
  7241.                         THIS.AddProp(M_ENABLED,.F.,m.btn)
  7242.                     ELSE
  7243.                         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED],m.btn)
  7244.                     ENDIF
  7245.                     IF "\!" $ m.capname
  7246.                         *- default, so strip out and set property
  7247.                         m.capname = STRTRAN(m.capname,"\!")
  7248.                         THIS.AddProp(M_DEFAULT,.T.,m.btn)
  7249.                     ENDIF
  7250.                     IF "\?" $ m.capname
  7251.                         *- escape/cancel, so strip out and set property
  7252.                         m.capname = STRTRAN(m.capname,"\?")
  7253.                         THIS.AddProp(M_CANCEL,.T.,m.btn)
  7254.                     ENDIF
  7255.                     THIS.AddProp(M_CAPTION,THIS.addquotes(m.capname),m.btn)
  7256.             ENDCASE
  7257.             
  7258.  
  7259.             *- Add mode (Opaque,Trans), and other attributes peculiar to btnName
  7260.             IF m.btnName = "Option"
  7261.                 *-THIS.AddMode(L_NOCONVERT,0,a_scx2fld[A_FILLPAT],m.btn)      && always transparent
  7262.                 THIS.AddMode(L_CONVERT,a_scx2fld[A_MODE],a_scx2fld[A_FILLPAT],m.btn)
  7263.                 *- Also add value for specific button
  7264.                 IF THIS.iValue = i
  7265.                     THIS.AddProp(M_VALUE,1,m.btn)
  7266.                 ENDIF
  7267.             ELSE
  7268.                 THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]-1),a_scx2fld[A_FILLPAT],m.btn)
  7269.             ENDIF
  7270.  
  7271.  
  7272.             THIS.AddProp(M_HEIGHT,m.unithgt,m.btn)
  7273.             THIS.AddProp(M_WIDTH,m.unitwid,m.btn)
  7274.             
  7275.             IF m.lishoriz  &&horizontal buttons
  7276.                 THIS.AddProp(M_HPOS,m.st_left+;
  7277.                     ((m.hspc+m.unitwid)*(m.i-1)),m.btn)
  7278.                 THIS.AddProp(M_VPOS,m.st_top,m.btn)
  7279.             ELSE
  7280.                 THIS.AddProp(M_HPOS,m.st_left,m.btn)
  7281.                 THIS.AddProp(M_VPOS,m.st_top+;
  7282.                     ((m.vspc+m.unithgt)*(m.i-1)),m.btn)
  7283.             ENDIF
  7284.             
  7285.             IF ATC("T",THIS.picword1) # 0    && terminate read
  7286.                 THIS.AddProp(M_TERMINATEREAD,.T.,m.btn)
  7287.             ELSE
  7288.                 THIS.AddProp(M_TERMINATEREAD,.F.,m.btn)
  7289.             ENDIF
  7290.  
  7291.             *- add releaseerase
  7292.             THIS.AddProp(M_RELEASEERASE,C_FALSE,m.btn)
  7293.  
  7294.             THIS.AddProp(M_NAME,m.btn,m.btn)
  7295.  
  7296.         ENDFOR
  7297.     ENDPROC            && fp25ctrl:AddGroup
  7298.  
  7299.     *----------------------
  7300.     PROCEDURE AddBtn        && fp25ctrl
  7301.     *----------------------
  7302.         IF ATC("B",THIS.picword1) # 0    && pictures
  7303.             THIS.AddProp(M_FPICTURE,THIS.FullBMP(THIS.picword2))
  7304.             THIS.AddProp(M_CAPTION,[""])
  7305.         ELSE
  7306.             THIS.AddProp(M_CAPTION,THIS.addquotes(THIS.picword2))
  7307.         ENDIF
  7308.         
  7309.         IF ATC("T",THIS.picword1) # 0    && terminate read
  7310.             THIS.AddProp(M_TERMINATEREAD,.T.)
  7311.         ELSE
  7312.             THIS.AddProp(M_TERMINATEREAD,.F.)
  7313.         ENDIF
  7314.  
  7315.     ENDPROC    && AddBtn
  7316.     
  7317.     *----------------------
  7318.     PROCEDURE AddValue    && fp25ctrl
  7319.     *----------------------
  7320.         *- This routine sets Value property to DEFAULT 
  7321.         *- setting for a Textbox,Editbox or Spinner 
  7322.         *- control similar to GENDEFAULT in GENSCRN.
  7323.         
  7324.         PRIVATE ctempstr,cfillchar,cinitval
  7325.         
  7326.         m.cfillchar = a_scx2fld[A_FILLCHAR]
  7327.         m.cinitval = TRIM(a_scx2fld[A_INITIALVAL])
  7328.         
  7329.         IF EMPTY(m.cinitval) AND EMPTY(m.cfillchar)
  7330.                RETURN
  7331.         ENDIF
  7332.         
  7333.         IF EMPTY(m.cinitval)
  7334.             DO CASE
  7335.                 CASE m.cfillchar = "D"
  7336.                       m.ctempstr = {  /  /  }
  7337.                 CASE m.cfillchar = "C" OR fillchar = "M" OR fillchar = "G"
  7338.                     RETURN
  7339.                 CASE m.cfillchar = "L"
  7340.                     m.ctempstr = .F.
  7341.                 CASE m.cfillchar = "N"
  7342.                       m.ctempstr = 0
  7343.                 CASE m.cfillchar= "F"
  7344.                     m.ctempstr = 0.0
  7345.             ENDCASE
  7346.         ELSE
  7347.             *- this only occurs with a spinner
  7348.             m.ctempstr = m.cinitval
  7349.         ENDIF
  7350.         THIS.AddProp(M_VALUE,m.ctempstr)
  7351.     ENDPROC            && fp25ctrl:AddValue
  7352.  
  7353. ENDDEFINE        &&  fp25ctrl
  7354.  
  7355.  
  7356. ************************************
  7357. DEFINE CLASS fp25list AS fp25ctrl
  7358. ************************************
  7359.  
  7360.     *----------------------
  7361.     PROCEDURE AddCtrl    && fp25list    
  7362.     *----------------------
  7363.  
  7364.         THIS.AddProp(M_EXPR,THIS.addquotes(a_scx2fld[A_EXPR]))
  7365.  
  7366.         *- add style specific stuff
  7367.         DO CASE
  7368.             CASE a_scx2fld[A_STYLE] = 0        && array
  7369.                 THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE],M_1STELEMENT)
  7370.                 THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE],M_NUMELEMENTS)
  7371.                 THIS.AddProp(M_LSTYLE,5)
  7372.                 THIS.AddProp(M_VALUE,1)        && set a default value, just in case
  7373.             CASE a_scx2fld[A_STYLE] = 1        && popup
  7374.                 THIS.AddProp(M_LSTYLE,9)
  7375.                 THIS.AddProp(M_VALUE,1)        && set a default value, just in case
  7376.             CASE a_scx2fld[A_STYLE] = 2        && DBF structure
  7377.                 THIS.AddProp(M_LSTYLE,8)
  7378.                 THIS.AddProp(M_VALUE,[" "])    && set a default value, just in case
  7379.             CASE a_scx2fld[A_STYLE] = 3        && field
  7380.                 THIS.AddProp(M_LSTYLE,6)
  7381.                 THIS.AddProp(M_VALUE,[" "])    && set a default value, just in case
  7382.             CASE a_scx2fld[A_STYLE] = 4        && file skeleton
  7383.                 THIS.AddProp(M_LSTYLE,7)
  7384.                 THIS.AddProp(M_VALUE,[" "])    && set a default value, just in case
  7385.         ENDCASE
  7386.  
  7387.         IF ATC("T",THIS.picword1) # 0    && terminate read
  7388.             THIS.AddProp(M_TERMINATEREAD,.T.)
  7389.         ELSE
  7390.             THIS.AddProp(M_TERMINATEREAD,.F.)
  7391.         ENDIF
  7392.  
  7393.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7394.  
  7395.     ENDPROC
  7396.  
  7397.     *----------------------
  7398.     PROCEDURE AddPos    && fp25list
  7399.     *----------------------
  7400.         *- Lists need a ReadSize property, before top, left, height, width
  7401.         *- THIS.AddProp(M_READSIZE,.T.)
  7402.         THIS.fp3fudge = .2
  7403.         *- Add object positions in pixels (how FP3 stores it)
  7404.         *- VPOS,HPOS based on form font
  7405.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * (THIS.nDeffont1+THIS.nDeffont5))        
  7406.         THIS.AddProp(M_HPOS,(a_scx2fld[A_HPOS] - THIS.fp3fudge) * THIS.nDeffont6)
  7407.         
  7408.         *- HEIGHT,WIDTH based on object font
  7409.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  7410.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7411.             (THIS.fp3font1+THIS.fp3font5) + 2)            && the extra 2 is for the border, which wasn't included in 2.6 listbox height
  7412.  
  7413.     ENDPROC
  7414.  
  7415.     *----------------------
  7416.     PROCEDURE AddColor    && fp25list
  7417.     *----------------------
  7418.         *- lists use different properties for colors
  7419.         *- Add colorstuff
  7420.         *- Add pen color
  7421.         PARAMETER m.btn
  7422.  
  7423.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  7424.  
  7425.         IF a_scx2fld[A_PENRED] # -1
  7426.  
  7427.             THIS.AddProp(M_ITEMFORECOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  7428.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  7429.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  7430.         ENDIF
  7431.         
  7432.         *- Add fill color
  7433.         IF a_scx2fld[A_FILLRED] = -1
  7434.         ELSE                
  7435.             THIS.AddProp(M_ITEMBACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  7436.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  7437.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  7438.             THIS.AddProp(M_DISITEMBACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  7439.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  7440.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  7441.         ENDIF
  7442.  
  7443.     ENDPROC
  7444.  
  7445. ENDDEFINE
  7446.  
  7447.  
  7448. ************************************
  7449. DEFINE CLASS fp25btn AS fp25ctrl
  7450. ************************************
  7451.  
  7452.     *----------------------
  7453.     PROCEDURE AddCtrl
  7454.     *----------------------
  7455.         THIS.AddBtn
  7456.         
  7457.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7458.  
  7459.     ENDPROC
  7460.  
  7461. ENDDEFINE
  7462.  
  7463.  
  7464. ************************************
  7465. DEFINE CLASS fp25cbox AS fp25ctrl
  7466. ************************************
  7467.  
  7468.     *----------------------
  7469.     PROCEDURE AddCtrl
  7470.     *----------------------
  7471.         THIS.AddBtn
  7472.         
  7473.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7474.  
  7475.         IF ATC("B",THIS.picword1) # 0    && pictures
  7476.             THIS.AddProp(M_STYLE,1)
  7477.         ELSE
  7478.             THIS.AddProp(M_STYLE,0)
  7479.         ENDIF
  7480.         
  7481.         THIS.AddProp(M_VALUE,a_scx2fld[A_INITIALNUM])
  7482.     ENDPROC
  7483.  
  7484. ENDDEFINE
  7485.  
  7486.  
  7487. ************************************
  7488. DEFINE CLASS fp25btngrp AS fp25ctrl
  7489. ************************************
  7490.     
  7491.     PROCEDURE AddPos
  7492.     ENDPROC
  7493.  
  7494.     PROCEDURE WriteName
  7495.     ENDPROC
  7496.     
  7497.     PROCEDURE AddCtrl
  7498.         THIS.AddGroup("Command")
  7499.     ENDPROC
  7500.  
  7501.     *----------------------
  7502.     PROCEDURE AddColor            && fp25btngrp
  7503.     *----------------------
  7504.         PARAMETER m.btn
  7505.  
  7506.         *- buttons are colorless things
  7507.  
  7508.         *- but they still need a colorsource
  7509.         THIS.AddProp(M_COLORSOURCE,0,m.btn)
  7510.  
  7511.     ENDPROC
  7512.  
  7513.  
  7514. ENDDEFINE
  7515.  
  7516.  
  7517. ***************************************
  7518. DEFINE CLASS fp25invgrp AS fp25ctrl
  7519. ***************************************
  7520.     
  7521.     PROCEDURE AddPos
  7522.     ENDPROC
  7523.  
  7524.     PROCEDURE WriteName
  7525.     ENDPROC
  7526.     
  7527.     PROCEDURE AddCtrl
  7528.         THIS.AddGroup("Command",.T.)
  7529.         THIS.AddProp(M_VALUE,0)                    && set the default value
  7530.     ENDPROC
  7531.  
  7532. ENDDEFINE
  7533.  
  7534.  
  7535. ***************************************
  7536. DEFINE CLASS fp25invbtn AS fp25ctrl
  7537. ***************************************
  7538.  
  7539.     *----------------------
  7540.     PROCEDURE AddCtrl
  7541.     *----------------------
  7542.         THIS.AddBtn
  7543.         
  7544.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7545.  
  7546.         THIS.AddProp(M_STYLE,1)
  7547.     ENDPROC
  7548.  
  7549. ENDDEFINE
  7550.  
  7551.  
  7552. ************************************
  7553. DEFINE CLASS fp25get AS fp25ctrl
  7554. ************************************
  7555.     *----------------------
  7556.     PROCEDURE AddMain        && fp25get
  7557.     *----------------------
  7558.  
  7559.         fp25ctrl::AddMain
  7560.  
  7561.         *- Add alignment
  7562.         DO CASE
  7563.             CASE ATC("B",THIS.picword1) # 0                && left - num type
  7564.                 THIS.AddProp(M_ALIGN,0)
  7565.             CASE ATC("J",THIS.picword1) # 0                && right - char type
  7566.                 THIS.AddProp(M_ALIGN,1)
  7567.             CASE ATC("I",THIS.picword1) # 0                && center - char type
  7568.                 THIS.AddProp(M_ALIGN,2)
  7569.             CASE INLIST(TYPE(a_scx2fld[A_EXPR]),"N")    && num, so make right just    
  7570.                 THIS.AddProp(M_ALIGN,1)
  7571.         ENDCASE
  7572.     
  7573.         IF !EMPTY(THIS.picword3)
  7574.             *- check for color, color scheme, size, etc.
  7575.         ENDIF        
  7576.  
  7577.     ENDPROC    && AddMain
  7578.  
  7579.     *----------------------
  7580.     PROCEDURE AddCtrl        && fp25get
  7581.     *----------------------
  7582.         THIS.AddFormat
  7583.         THIS.AddValue
  7584.         
  7585.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7586.  
  7587.         THIS.AddProp(M_MARGIN,0)    && new 3.0 prop
  7588.  
  7589.         THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE])    && ,M_RANGELO)
  7590.         THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE])    && ,M_RANGEHI)
  7591.         THIS.AddProp(M_PENPAT,IIF(THIS.formRef.GetBorder,1,0))
  7592.  
  7593.         *- check for any #ITSE expressions
  7594.  
  7595.         IF !EMPTY(THIS.picword3)
  7596.             *- additional checks
  7597.         ENDIF
  7598.     ENDPROC
  7599.     
  7600.     *----------------------
  7601.     PROCEDURE AddPos        && fp25get
  7602.     *----------------------
  7603.         *- Add object positions in pixels (how Taz stores it)
  7604.         *- FP2.5 added extra pixels for some reason
  7605.         *- VPOS = -1, HPOS = -2, WIDTH = 5,HEIGHT = 2
  7606.         *- VPOS,HPOS based on form font
  7607.         THIS.AddProp(M_VPOS, a_scx2fld[A_VPOS] * ;
  7608.             (THIS.nDeffont1 + THIS.nDeffont5) - 1)        
  7609.         THIS.AddProp(M_HPOS, a_scx2fld[A_HPOS] * THIS.nDeffont6 - 2)
  7610.         
  7611.         *- HEIGHT,WIDTH based on object font
  7612.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6 + 5)
  7613.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7614.                 (THIS.fp3font1+THIS.fp3font5) + 2)
  7615.     ENDPROC
  7616.  
  7617. ENDDEFINE && fp25get
  7618.  
  7619.  
  7620. ************************************
  7621. DEFINE CLASS fp25text AS fp25ctrl
  7622. ************************************
  7623.     *- superclass for textboxes and says
  7624.  
  7625.     *----------------------
  7626.     PROCEDURE AddMain        && fp25text
  7627.     *----------------------
  7628.  
  7629.         fp25ctrl::AddMain
  7630.  
  7631.         *- Add alignment
  7632.         DO CASE
  7633.             CASE ATC("B",THIS.picword1) # 0                && left - num type
  7634.                 THIS.AddProp(M_ALIGN,0)
  7635.             CASE ATC("J",THIS.picword1) # 0                && right - char type
  7636.                 THIS.AddProp(M_ALIGN,1)
  7637.             CASE ATC("I",THIS.picword1) # 0                && center - char type
  7638.                 THIS.AddProp(M_ALIGN,2)
  7639.             CASE INLIST(TYPE(a_scx2fld[A_EXPR]),"N")    && num, so make right just    
  7640.                 THIS.AddProp(M_ALIGN,1)
  7641.         ENDCASE
  7642.     
  7643.         IF !EMPTY(THIS.picword3)
  7644.             *- check for color, color scheme, size, etc.
  7645.         ENDIF        
  7646.  
  7647.     ENDPROC    && AddMain
  7648.  
  7649.     *----------------------
  7650.     PROCEDURE AddCtrl        && fp25text
  7651.     *----------------------
  7652.         THIS.AddFormat
  7653.         THIS.AddValue
  7654.  
  7655.         THIS.AddProp(M_MARGIN,0)    && new 3.0 prop
  7656.  
  7657.     ENDPROC
  7658.  
  7659.     *----------------------
  7660.     PROCEDURE AddPos        && fp25text
  7661.     *----------------------
  7662.         *- Add object positions in pixels (how Taz stores it)
  7663.         *- FP2.5 added extra pixels for some reason
  7664.         *- VPOS = -1, HPOS = -2, WIDTH = 2,HEIGHT = 2
  7665.         *- VPOS,HPOS based on form font
  7666.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS] * ;
  7667.             (THIS.nDeffont1 + THIS.nDeffont5)-1)        
  7668.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS] * THIS.nDeffont6-2)
  7669.         
  7670.         *- HEIGHT,WIDTH based on object font
  7671.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6+2)
  7672.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7673.                 (THIS.fp3font1 + THIS.fp3font5) + 2)
  7674.     ENDPROC
  7675.  
  7676.  
  7677. ENDDEFINE    && fp25text
  7678.  
  7679. ************************************
  7680. DEFINE CLASS fp25edit AS fp25text
  7681. ************************************
  7682.  
  7683.     *----------------------
  7684.     PROCEDURE AddCtrl
  7685.     *----------------------
  7686.         fp25text::AddCtrl
  7687.  
  7688.         IF !a_scx2fld[A_SCROLLBAR]
  7689.             THIS.AddProp(M_SCROLLBAR,0)
  7690.         ENDIF
  7691.         
  7692.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7693.  
  7694.         THIS.AddProp(M_TAB,a_scx2fld[A_TAB])
  7695.         *-THIS.AddProp(M_MAXLEN,a_scx2fld[A_INITIALNUM])
  7696.         *-THIS.AddProp(M_PENPAT,IIF(THIS.formRef.GetBorder,1,0))
  7697.         *- check if person has .T. NOMODIFY kludge
  7698.         IF  ATC(" NOMO",THIS.fp3method) # 0 OR ;
  7699.             ATC(" NOMO",THIS.picword3) # 0
  7700.             *- comment out NOMODIFY in methods. Leave alone in picture clause
  7701.             THIS.fp3method = STRTRAN(THIS.fp3method," NOMO"," &" + "& NOMO")
  7702.             THIS.AddProp(M_READONLY,C_TRUE)
  7703.         ENDIF
  7704.     ENDPROC
  7705.  
  7706.     *----------------------
  7707.     PROCEDURE AddValue    && fp25edit
  7708.     *----------------------
  7709.         *- This routine sets Value property to DEFAULT 
  7710.         *- Editbox. Overrides the fp25ctrl:AddValue
  7711.         *- 2.6 allowed a numeric type for the editbox, which is not allowed in 3.0
  7712.         
  7713.         RETURN
  7714.         
  7715.     ENDPROC            && fp25edit:AddValue
  7716.  
  7717. ENDDEFINE && fp25edit
  7718.  
  7719. ************************************
  7720. DEFINE CLASS fp25say AS fp25text
  7721. ************************************
  7722.     *- a read-only descendent of fp25text
  7723.  
  7724.     *----------------------
  7725.     PROCEDURE AddCtrl
  7726.     *----------------------
  7727.         fp25text::AddCtrl
  7728.  
  7729.         THIS.AddProp(M_STYLE,1)            && should set behavior like 2.6 SAY
  7730.         THIS.AddProp(M_READONLY,.T.)    && can't change it
  7731.         THIS.AddProp(M_TABSTOP,.F.)        && can't tab into it
  7732.         *-THIS.AddProp(M_ENABLED,.F.)        && disabled
  7733.  
  7734.         THIS.AddProp(M_PENPAT,0)        && no border
  7735.  
  7736.     ENDPROC
  7737.  
  7738.     *----------------------
  7739.     FUNCTION GetNewName    && fp25say
  7740.     *----------------------
  7741.         *- use as much of EXPR as possible
  7742.         PARAMETER newobj
  7743.         LOCAL cName
  7744.  
  7745.         m.cName = ALLT(StripQuote(ALLT(a_scx2fld[A_EXPR])))
  7746.         IF !EMPTY(m.cName)
  7747.             m.cName = LEFT(m.cName,MIN(LEN(m.cName),8))
  7748.             m.newobj = THIS.GetVarPrefix(newobj) + ALLT(PROPER(GoodName(m.cName)))
  7749.         ELSE
  7750.             m.newobj = THIS.GetVarPrefix(newobj) + PROPER(m.newobj)
  7751.         ENDIF
  7752.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  7753.         RETURN ALLTRIM(m.newobj) + ALLTRIM(STR(THIS.formRef.nObjCount))
  7754.     ENDFUNC        &&  GetNewName
  7755.  
  7756.     *----------------------
  7757.     PROCEDURE AddColor    && fp25say
  7758.     *----------------------
  7759.         *- Add colorstuff
  7760.         *- Add pen color
  7761.         PARAMETER m.btn
  7762.  
  7763.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE)
  7764.  
  7765.         *- since SAYs are handled as disabled textboxes, make the disabled colors and
  7766.         *- the enabled colors the same as the 2.6 colors
  7767.         IF a_scx2fld[A_PENRED] = -1
  7768.         ELSE
  7769.             THIS.AddProp(M_DISFORECOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  7770.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  7771.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  7772.             THIS.AddProp(M_PEN,ALLT(STR(a_scx2fld[A_PENRED]))+;
  7773.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  7774.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  7775.         ENDIF
  7776.  
  7777.         IF a_scx2fld[A_FILLRED] = -1
  7778.         ELSE
  7779.             THIS.AddProp(M_BACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  7780.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  7781.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  7782.         ENDIF
  7783.  
  7784.     ENDPROC
  7785.  
  7786.     *----------------------
  7787.     PROCEDURE AddValue        && fp25say
  7788.     *----------------------
  7789.         LOCAL m.cExpr, m.cParent
  7790.  
  7791.         DO CASE
  7792.             CASE !EMPTY(a_scx2fld[A_EXPR]) AND ;
  7793.                 AT(LEFT(a_scx2fld[A_EXPR],1),["[']) # 0
  7794.                 m.cExpr = a_scx2fld[A_EXPR]
  7795.             CASE !INLIST(TYPE(a_scx2fld[A_EXPR]),"C","M","U","N")
  7796.                 m.cExpr = "(" + THIS.Conv2Str(a_scx2fld[A_EXPR]) + ")"
  7797.             OTHERWISE
  7798.                 m.cExpr = a_scx2fld[A_EXPR]
  7799.         ENDCASE
  7800.  
  7801.         THIS.AddProp(M_VALUE,m.cExpr)
  7802.  
  7803.         IF a_scx2fld[A_REFRESH]
  7804.             *- add to READSHOW method of formset
  7805.             IF THIS.FormRef.lIndirectWinName
  7806.                 *- need to slip in ref to the new, changed form name
  7807.                 m.cParent = "THISFORMSET." + CHR(38) + THIS.FormRef.cIndirectWinName + ".." + ;
  7808.                     SUBS(THIS.fp3parent,AT(".",THIS.fp3parent,2) + 1)
  7809.             ELSE
  7810.                 m.cParent = "THISFORMSET." + ;
  7811.                     SUBS(THIS.fp3parent,AT(".",THIS.fp3parent,1) + 1)
  7812.             ENDIF
  7813.  
  7814.             THIS.formRef.cReadShow = THIS.formRef.cReadShow + ;
  7815.                 m.cParent + "." + THIS.fp3name + ".Value = " + ;
  7816.                 m.cExpr + C_CRLF
  7817.         ENDIF
  7818.  
  7819.     ENDPROC
  7820.  
  7821. ENDDEFINE && fp25say
  7822.  
  7823. ************************************
  7824. DEFINE CLASS fp25option AS fp25ctrl
  7825. ************************************
  7826. *- this class allows both radios and popups to inherit this AddValue
  7827.  
  7828.     iValue = 0                && need to remember the value, so the individual option button value can be set
  7829.  
  7830.     *----------------------
  7831.     PROCEDURE AddValue
  7832.     *----------------------
  7833.         *- This routine sets Value property to DEFAULT 
  7834.         *- setting for a popup/combobox
  7835.         *- control similar to GENDEFAULT in GENSCRN.
  7836.         
  7837.         LOCAL ctempval,cinitval,ctemp2
  7838.         
  7839.         m.cinitval = ALLT(a_scx2fld[A_INITIALVAL])
  7840.         m.ctemp2 = SUBS(m.cinitval,2,LEN(m.cinitval) - 2)
  7841.         
  7842.         DO CASE
  7843.             CASE EMPTY(m.cinitval)
  7844.                 m.ctempval = 1
  7845.             CASE ALLT(STR(VAL(m.cinitval))) = m.cinitval
  7846.                 *- is a number
  7847.                 m.ctempval = VAL(m.cinitval)
  7848.             CASE THIS.fp25OC = 3
  7849.                 *- from array -- set to 1
  7850.                 m.ctempval = 1
  7851.             OTHERWISE
  7852.                 *- text -- do without the quotes
  7853.                 m.ctempval = m.cinitval
  7854.         ENDCASE
  7855.         
  7856.         THIS.AddProp(M_VALUE,m.ctempval)
  7857.         THIS.iValue = m.ctempval
  7858.  
  7859.     ENDPROC    && AddValue
  7860.  
  7861. ENDDEFINE    && fp25option
  7862.  
  7863.  
  7864. ************************************
  7865. DEFINE CLASS fp25radio AS fp25option
  7866. ************************************
  7867.     
  7868.     PROCEDURE AddPos
  7869.     ENDPROC
  7870.  
  7871.     PROCEDURE WriteName
  7872.     ENDPROC
  7873.  
  7874.     *----------------------
  7875.     PROCEDURE AddMain        && fp25radio
  7876.     *----------------------
  7877.  
  7878.         fp25option::AddMain
  7879.  
  7880.         THIS.AddGroup("Option",.F.,.T.)        && Add button groups AFTER ControlSource is set
  7881.  
  7882.     ENDPROC
  7883.  
  7884.  
  7885.     *----------------------
  7886.     PROCEDURE AddCtrl        && fp25radio
  7887.     *----------------------
  7888.         *- set initial value
  7889.         
  7890.         *- set group Enabled property to .T., and individual buttons to whatever
  7891.         THIS.AddProp(M_ENABLED,.T.)
  7892.  
  7893.         IF ATC("B",THIS.picword1) = 0    && text radios
  7894.             THIS.AddProp(M_VALUE,a_scx2fld[A_INITIALNUM])
  7895.             THIS.iValue = a_scx2fld[A_INITIALNUM]
  7896.         ENDIF
  7897.  
  7898.     ENDPROC
  7899.  
  7900.     *----------------------
  7901.     PROCEDURE AddMode        && fp25radio
  7902.     *----------------------
  7903.         *- add the mode (opaque/transparent)
  7904.         *- if mode has to be converted, check for opaque w/ no fill pat
  7905.         PARAMETER lConvert,nMode,nFillPat,m.btn
  7906.  
  7907.         IF a_scx2fld[A_FILLRED] = -1
  7908.             *- force transparent mode if auto color
  7909.             THIS.AddProp(M_MODE,N_TRANSPARENT,m.btn)
  7910.         ELSE
  7911.             fp25option::AddMode(lConvert,nMode,nFillPat,m.btn)
  7912.         ENDIF
  7913.     ENDPROC
  7914.  
  7915. ENDDEFINE    && fp25radio
  7916.  
  7917.  
  7918. ************************************
  7919. DEFINE CLASS fp25popup AS fp25option
  7920. ************************************
  7921.  
  7922.     *----------------------
  7923.     PROCEDURE AddCtrl
  7924.     *----------------------
  7925.         LOCAL cListSource
  7926.         
  7927.         THIS.AddProp(M_STYLE,2)
  7928.         
  7929.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7930.  
  7931.         *- combo box items must appear in the following order:
  7932.         *- rowSource, rowSourceType, value, dataSource
  7933.         IF THIS.fp25OC = 1  && list popups
  7934.             THIS.AddProp(M_1STELEMENT,a_scx2fld[A_INITIALNUM])
  7935.             m.cListSource = STRTRAN(STRTRAN(THIS.picword2,",","."),";",",")    && FP 3.0 delimits popups with commas,
  7936.             THIS.AddProp(M_EXPR,THIS.addquotes(m.cListSource))                && so attempt to preserve commas that are there
  7937.             THIS.AddProp(M_LSTYLE,1)                                        && Style = VALUE (1)
  7938.         ELSE                  && array popups
  7939.             THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE],M_1STELEMENT)
  7940.             THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE],M_NUMELEMENTS)
  7941.             THIS.AddProp(M_LSTYLE,5)
  7942.             THIS.AddProp(M_EXPR,THIS.addquotes(a_scx2fld[A_EXPR]))
  7943.         ENDIF
  7944.         
  7945.         THIS.AddValue
  7946.  
  7947.     ENDPROC
  7948.  
  7949. ENDDEFINE    && fp25popup
  7950.  
  7951. ************************************
  7952. DEFINE CLASS fp25spin AS fp25ctrl
  7953. ************************************
  7954.  
  7955.     PROCEDURE AddCtrl
  7956.         THIS.AddFormat
  7957.         THIS.AddValue
  7958.         
  7959.         THIS.AddProp(M_ENABLED,!a_scx2fld[A_DISABLED])
  7960.  
  7961.         THIS.AddProp(M_MARGIN,0)    && new 3.0 prop
  7962.  
  7963.         THIS.AddProp(M_ALIGN,1)        && force right align
  7964.  
  7965.         *- only add spinner high and low values if they have been set
  7966.         IF !EMPTY(a_scx2fld[A_TAG])
  7967.             THIS.AddProp(M_SPINLO,a_scx2fld[A_TAG])
  7968.         ENDIF
  7969.         IF !EMPTY(a_scx2fld[A_TAG2])
  7970.             THIS.AddProp(M_SPINHI,a_scx2fld[A_TAG2])
  7971.         ENDIF
  7972.  
  7973.         THIS.AddMethods(M_RANGE2LO,a_scx2fld[A_RANGELO],a_scx2fld[A_LOTYPE],M_KEYLO)
  7974.         THIS.AddMethods(M_RANGE2HI,a_scx2fld[A_RANGEHI],a_scx2fld[A_HITYPE],M_KEYHI)
  7975.     ENDPROC
  7976.  
  7977.     *----------------------
  7978.     PROCEDURE AddPos        && fp25spin
  7979.     *----------------------
  7980.         *- Add object positions in pixels (how FP3 stores it)
  7981.         *- VPOS,HPOS based on form font
  7982.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.nDeffont1+THIS.nDeffont5))        
  7983.         THIS.AddProp(M_HPOS,(a_scx2fld[A_HPOS] - .6) * THIS.nDeffont6)
  7984.         
  7985.         *- HEIGHT,WIDTH based on object font
  7986.         *- Spinner needs extra 19 pixels width for spinner control
  7987.         *-               extra  6 pixels height
  7988.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6 + 19)
  7989.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT] * ;
  7990.                 (THIS.fp3font1+THIS.fp3font5) + 7)
  7991.     ENDPROC
  7992.  
  7993.     *----------------------
  7994.     PROCEDURE AddValue    && fp25spin
  7995.     *----------------------
  7996.         *- This routine sets Value property to DEFAULT 
  7997.         
  7998.         LOCAL cinitval
  7999.  
  8000.         IF !EMPTY(a_scx2fld[A_INITIALVAL])
  8001.             IF INT(VAL(a_scx2fld[A_INITIALVAL])) <> VAL(a_scx2fld[A_INITIALVAL])
  8002.                 cinitval = ForceDec(a_scx2fld[A_INITIALVAL],;
  8003.                     LEN(a_scx2fld[A_INITIALVAL]) - AT('.',a_scx2fld[A_INITIALVAL]))
  8004.             ELSE
  8005.                 cinitval = ForceDec(a_scx2fld[A_INITIALVAL],3)
  8006.             ENDIF
  8007.         ELSE
  8008.             cinitval = "1.000"
  8009.         ENDIF
  8010.                 
  8011.         THIS.AddProp(M_SPININC,cinitval)
  8012.  
  8013.         DO CASE
  8014.             CASE !EMPTY(TAG)
  8015.                 m.cinitval = ForceDec(TRIM(a_scx2fld[A_TAG]),3)
  8016.                 THIS.AddProp(M_VALUE,m.cinitval)
  8017.             CASE !EMPTY(tag2)
  8018.                 m.cinitval = ForceDec(TRIM(a_scx2fld[A_TAG2]),3)
  8019.                 THIS.AddProp(M_VALUE,m.cinitval)
  8020.             CASE EMPTY(TRIM(initialval))
  8021.                 m.cinitval = "1"
  8022.                 THIS.AddProp(M_VALUE,m.cinitval)
  8023.             OTHERWISE
  8024.                fp25ctrl::AddValue
  8025.         ENDCASE
  8026.  
  8027.            RETURN
  8028.         
  8029. ENDDEFINE
  8030.  
  8031.  
  8032. ************************************
  8033. DEFINE CLASS fp25lbl AS fp25obj
  8034. ************************************
  8035. *- Text objects
  8036.     
  8037.     *----------------------
  8038.     PROCEDURE AddMain        && fp25lbl
  8039.     *----------------------
  8040.  
  8041.         *- Add label specific properties
  8042.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8043.  
  8044.         *- Get parts of Picture clause for use below
  8045.         THIS.GetPicPart(a_scx2fld[A_PICTURE])
  8046.  
  8047.         IF THIS.fp25OT = 15    && @..SAY
  8048.             DO CASE
  8049.                 CASE !EMPTY(a_scx2fld[A_EXPR]) AND ;
  8050.                     AT(LEFT(a_scx2fld[A_EXPR],1),["[']) # 0
  8051.                     THIS.AddProp(M_CAPTION,a_scx2fld[A_EXPR])
  8052.                 CASE !INLIST(TYPE(a_scx2fld[A_EXPR]),"C","M","U")
  8053.                     THIS.AddProp(M_CAPTION,THIS.Conv2Str(a_scx2fld[A_EXPR]))
  8054.                 OTHERWISE
  8055.                     THIS.AddProp(M_CAPTION,a_scx2fld[A_EXPR])
  8056.             ENDCASE
  8057.             
  8058.             THIS.picword2 = ""
  8059.             THIS.AddFormat
  8060.         ELSE
  8061.             THIS.AddProp(M_CAPTION,STRTRAN(a_scx2fld[A_EXPR],CHR(13),'" + CHR(13) + "'))
  8062.         ENDIF
  8063.  
  8064.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE)
  8065.  
  8066.         *- Add mode (Opaque,Trans)
  8067.         THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),1)    && labels have no fill
  8068.  
  8069.         *- Add alignment
  8070.         DO CASE
  8071.             CASE ATC("B",THIS.picword1) # 0    && left - num type
  8072.                 THIS.AddProp(M_ALIGN,0)
  8073.             CASE ATC("J",THIS.picword1) # 0    && right - char type
  8074.                 THIS.AddProp(M_ALIGN,1)
  8075.             CASE ATC("I",THIS.picword1) # 0    && center - char type
  8076.                 THIS.AddProp(M_ALIGN,2)
  8077.         ENDCASE
  8078.     
  8079.         IF !EMPTY(THIS.picword3)
  8080.             *- check for color, color scheme, size, etc.
  8081.         ENDIF        
  8082.  
  8083.         *- add releaseerase
  8084.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8085.  
  8086.     ENDPROC    && AddMain
  8087.  
  8088.     *----------------------
  8089.     FUNCTION GetNewName    && fp25lbl
  8090.     *----------------------
  8091.         *- use as much of EXPR as possible
  8092.         PARAMETER newobj
  8093.         LOCAL cName
  8094.  
  8095.         m.cName = ALLT(StripQuote(ALLT(a_scx2fld[A_EXPR])))
  8096.         IF !EMPTY(m.cName)
  8097.             m.cName = LEFT(m.cName,MIN(LEN(m.cName),8))
  8098.             m.newobj = THIS.GetVarPrefix(m.newobj) + PROPER(GoodName(m.cName))
  8099.         ELSE
  8100.             m.newobj = THIS.GetVarPrefix(m.newobj) + PROPER(m.newobj)
  8101.         ENDIF
  8102.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  8103.         RETURN ALLTRIM(m.newobj) + ALLTRIM(STR(THIS.formRef.nObjCount))
  8104.     ENDFUNC        &&  GetNewName
  8105.  
  8106.  
  8107. ENDDEFINE && fp25lbl
  8108.  
  8109.  
  8110. ************************************
  8111. DEFINE CLASS fp25shape AS fp25obj
  8112. ************************************
  8113.  
  8114.     *----------------------
  8115.     PROCEDURE AddBasic        && fp25shape
  8116.     *----------------------
  8117.         fp25obj::AddBasic
  8118.         THIS.fp3id = SYS(2015)        && we'll sort on this field later
  8119.     ENDPROC
  8120.  
  8121.  
  8122.     *- support 3-d from FoxMac 2.6 (12/5/95 jd)
  8123.     *----------------------
  8124.     PROCEDURE AddFX        && fp25shape
  8125.     *----------------------
  8126.         *- Add Special Effects
  8127.         PARAMETER btn
  8128.         IF a_scx2fld[A_PLATFORM] = C_MAC AND a_scx2fld[A_PENPAT] == 100 AND a_scx2fld[A_PENSIZE] == 2
  8129.             a_scx2fld[A_PENSIZE] = 1        && change this so new crame looks right
  8130.             THIS.AddProp(M_SPECIAL,N_3D)
  8131.         ELSE
  8132.             THIS.AddProp(M_SPECIAL,N_PLAIN)
  8133.         ENDIF
  8134.     ENDPROC
  8135.  
  8136.     *----------------------
  8137.     PROCEDURE AddMain        && fp25shape
  8138.     *----------------------
  8139.  
  8140.         LOCAL m.nFillPat
  8141.  
  8142.         *- Now add shape specific properties
  8143.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8144.         
  8145.         *- add 3-d if necessary -- do this right away, because it might
  8146.         *- change the PENSIZE value
  8147.         THIS.AddFx
  8148.  
  8149.         IF THIS.fp25OT = 7        && normal boxes
  8150.             DO CASE
  8151.                 CASE a_scx2fld[A_FILLPAT] = 0
  8152.                     m.nFillPat = 1
  8153.                 CASE a_scx2fld[A_FILLPAT] = 1
  8154.                     m.nFillPat = 0
  8155.                 CASE a_scx2fld[A_FILLPAT] = 4
  8156.                     m.nFillPat = 5
  8157.                 CASE a_scx2fld[A_FILLPAT] = 5
  8158.                     m.nFillPat = 4
  8159.                 OTHERWISE
  8160.                     m.nFillPat = a_scx2fld[A_FILLPAT]
  8161.             ENDCASE
  8162.  
  8163.             THIS.AddProp(M_FILLPAT,m.nFillPat)
  8164.             IF m.nFillPat = 1                && FillStyle 1 = transparent/none, 0 = opaque/solid
  8165.                 *- If FillPat is transparent, also set BackStyle to transparent
  8166.                 THIS.AddProp(M_MODE,0)        && BackStyle 0 = transparent/none, 1 = opaque/solid
  8167.             ELSE
  8168.                 *- Add mode (Opaque,Trans)
  8169.                 THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8170.             ENDIF
  8171.         ELSE
  8172.                 *- Add mode (Opaque,Trans)
  8173.                 THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8174.         ENDIF        
  8175.  
  8176.         *- Add rounded rectangle stuff
  8177.         IF    a_scx2fld[A_STYLE] >= 12
  8178.             *THIS.AddProp(M_SHAPE,4)
  8179.             THIS.AddProp(M_CURVE,a_scx2fld[A_STYLE])
  8180.         ENDIF
  8181.  
  8182.         *- Add pen width
  8183.         THIS.AddProp(M_PENSIZE,MAX(a_scx2fld[A_PENSIZE],1))
  8184.         
  8185.         *- Add pen pattern
  8186.         DO CASE
  8187.             CASE a_scx2fld[A_PENPAT] = 8    && solid
  8188.                 *- default of 8 in 2.6/1 in VFP, so no need to add
  8189.             CASE a_scx2fld[A_PENPAT] = 1    && dotted
  8190.                 THIS.AddProp(M_PENPAT,3)            
  8191.             CASE a_scx2fld[A_PENPAT] = 2    && dashed
  8192.                 THIS.AddProp(M_PENPAT,2)            
  8193.             CASE a_scx2fld[A_PENPAT] = 3    && dash dot
  8194.                 THIS.AddProp(M_PENPAT,4)            
  8195.             CASE a_scx2fld[A_PENPAT] = 4    && dash dot dot
  8196.                 THIS.AddProp(M_PENPAT,5)        
  8197.             CASE a_scx2fld[A_PENPAT] = 0    && "none"
  8198.                 THIS.AddProp(M_PENPAT,0)
  8199.         ENDCASE
  8200.  
  8201.         *- add ReleaseErase
  8202.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8203.         
  8204.     ENDPROC
  8205.  
  8206.     *----------------------
  8207.     PROCEDURE AddFont
  8208.     *----------------------
  8209.     ENDPROC
  8210.     
  8211.     *----------------------
  8212.     PROCEDURE AddPos        && fp25shape
  8213.     *----------------------
  8214.         *- VPOS,HPOS based on form font
  8215.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))        
  8216.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS]*THIS.formRef.nDeffont6)
  8217.         DO CASE
  8218.             CASE THIS.fp25OT = 6        &&lines
  8219.                 IF a_scx2fld[A_STYLE] = 0 && vertical line
  8220.                     THIS.AddProp(M_WIDTH,0)
  8221.                     THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))
  8222.                 ELSE
  8223.                     THIS.AddProp(M_HEIGHT,0)
  8224.                     THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH]*THIS.formRef.nDeffont6)
  8225.                 ENDIF
  8226.             CASE THIS.fp25OT = 7        &&boxes
  8227.                 THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))
  8228.                 THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH]*THIS.formRef.nDeffont6)
  8229.         ENDCASE
  8230.     ENDPROC
  8231.  
  8232.     *----------------------
  8233.     PROCEDURE AddColor        && fp25shape
  8234.     *----------------------
  8235.         *- Add colorstuff
  8236.         *- Add pen color
  8237.         PARAMETER m.btn
  8238.  
  8239.         LOCAL lColorSource
  8240.  
  8241.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  8242.  
  8243.         IF a_scx2fld[A_PENRED] # -1
  8244.             THIS.AddProp(M_BORDERCOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  8245.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  8246.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  8247.         ENDIF
  8248.         
  8249.         *- Add fill color
  8250.         IF a_scx2fld[A_FILLRED] = -1
  8251.             RETURN
  8252.         ENDIF
  8253.                 
  8254.         THIS.AddProp(M_FILLCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  8255.             ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  8256.             ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  8257.         THIS.AddProp(M_BACKCOLOR,"255,255,255")
  8258.  
  8259.         *- set disabled color to be the same as the enabled color
  8260.         THIS.AddProp(M_DISFORECOLOR,ALLT(STR(a_scx2fld[A_PENRED])) + ;
  8261.             ","+ALLT(STR(a_scx2fld[A_PENGREEN])) + ;
  8262.             ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  8263.  
  8264.     ENDPROC
  8265.     
  8266. ENDDEFINE && fp25shape 
  8267.  
  8268. ************************************
  8269. DEFINE CLASS fp25line AS fp25shape
  8270. ************************************
  8271.     *- override AddColor
  8272.     *----------------------
  8273.     PROCEDURE AddColor
  8274.     *----------------------
  8275.         *- Add colorstuff
  8276.         *- Add pen color
  8277.         PARAMETER m.btn
  8278.  
  8279.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  8280.  
  8281.         IF a_scx2fld[A_PENRED] # -1
  8282.             THIS.AddProp(M_BORDERCOLOR,ALLT(STR(a_scx2fld[A_PENRED]))+;
  8283.                 ","+ALLT(STR(a_scx2fld[A_PENGREEN]))+;
  8284.                 ","+ALLT(STR(a_scx2fld[A_PENBLUE])))
  8285.         ENDIF
  8286.         
  8287.         *- Add fill color
  8288.         IF a_scx2fld[A_FILLRED] = -1
  8289.             RETURN
  8290.         ENDIF
  8291.                 
  8292.         THIS.AddProp(M_BACKCOLOR,ALLT(STR(a_scx2fld[A_FILLRED]))+;
  8293.             ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  8294.             ","+ALLT(STR(a_scx2fld[A_FILLBLUE])))
  8295.  
  8296.     ENDPROC
  8297.  
  8298. ENDDEFINE && fp25line 
  8299.  
  8300. ************************************
  8301. DEFINE CLASS fp25pict AS fp25obj
  8302. ************************************
  8303.  
  8304.     *----------------------
  8305.     PROCEDURE AddBasic        && fp25pict
  8306.     *----------------------
  8307.         fp25obj::AddBasic
  8308.         THIS.fp3id = SYS(2015)        && we'll sort on this field later
  8309.     ENDPROC
  8310.  
  8311.     *----------------------
  8312.     PROCEDURE AddMain        && fp25pict
  8313.     *----------------------
  8314.     
  8315.         *- Now add form properties
  8316.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8317.         
  8318.         *- Add picture for BMP file
  8319.         IF a_scx2fld[A_STYLE] = 0
  8320.             *- source of picture is a file, stored in PICTURE field
  8321.             THIS.AddProp(M_FPICTURE,THIS.FullBMP(EVAL(a_scx2fld[A_PICTURE])))
  8322.         ELSE
  8323.             IF (" BITMAP" $ UPPER(a_scx2fld[A_NAME]))
  8324.             *-IF    ("\" $ ALLT(a_scx2fld[A_NAME])) OR ;
  8325.                 ("." $ ALLT(a_scx2fld[A_NAME])) OR ;
  8326.                 (":" $ ALLT(a_scx2fld[A_NAME])) OR ;
  8327.                 ('"' $ ALLT(a_scx2fld[A_NAME])) OR ;
  8328.                 (" " $ ALLT(a_scx2fld[A_NAME]))
  8329.                 *- assume is filename of form <filename><space>BITMAP
  8330.                 THIS.AddProp(M_FPICTURE,"(" + LEFT(ALLT(a_scx2fld[A_NAME]), AT(" ",ALLT(a_scx2fld[A_NAME])) - 1) + ")")
  8331.             ELSE
  8332.                 THIS.AddProp(M_FPICTURE,"(" + THIS.GetNewName(THIS.fp3class) + ")")
  8333.             ENDIF
  8334.         ENDIF
  8335.  
  8336.         *- Add mode (Opaque,Trans)
  8337.         THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8338.  
  8339.         *- add ReleaseErase
  8340.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8341.                 
  8342.     ENDPROC
  8343.  
  8344.     *----------------------
  8345.     PROCEDURE AddPos        && fp25pict
  8346.     *----------------------
  8347.         *- Add stretch mode before height, width, etc.
  8348.         THIS.AddProp(M_STRETCH,a_scx2fld[A_BORDER])
  8349.  
  8350.         *- VPOS,HPOS based on form font
  8351.         THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))        
  8352.         THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS]*THIS.formRef.nDeffont6)
  8353.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*(THIS.formRef.nDeffont1+THIS.formRef.nDeffont5))
  8354.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH]*THIS.formRef.nDeffont6)
  8355.     ENDPROC    
  8356.     
  8357.     *----------------------
  8358.     PROCEDURE AddFont
  8359.     *----------------------
  8360.     ENDPROC
  8361.     
  8362.     PROCEDURE AddColor
  8363.         PARAMETER m.btn
  8364.         THIS.AddProp(M_COLORSOURCE,I_DEFCOLORSOURCE,m.btn)
  8365.     ENDPROC
  8366.  
  8367.  
  8368. ENDDEFINE && fp25pict
  8369.  
  8370. ************************************
  8371. DEFINE CLASS fp25ole AS fp25pict
  8372. ************************************
  8373.  
  8374.     *----------------------
  8375.     PROCEDURE AddMain        && fp25ole
  8376.     *----------------------
  8377.     
  8378.         *- Now add form properties
  8379.         THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8380.         
  8381.         *- Add mode (Opaque,Trans)
  8382.         THIS.AddMode(L_CONVERT,ABS(a_scx2fld[A_MODE]),a_scx2fld[A_FILLPAT])
  8383.  
  8384.         *- add ReleaseErase
  8385.         THIS.AddProp(M_RELEASEERASE,C_FALSE)
  8386.  
  8387.         *- Add datasource (general field name)
  8388.         THIS.AddProp(M_DATASOURCE,ALLTRIM(a_scx2fld[A_NAME]))
  8389.  
  8390.         *- other specific actions for OLEBoundControls
  8391.         THIS.AddCtrl
  8392.  
  8393.     ENDPROC
  8394.     
  8395.     *----------------------
  8396.     PROCEDURE AddCtrl        && fp25ole
  8397.     *----------------------
  8398.         
  8399.         THIS.AddProp(M_ENABLED,.F.)
  8400.         THIS.AddProp(M_GROW,.F.)
  8401.         THIS.AddProp(M_AUTOACTIVATE,0)        && manual
  8402.  
  8403.     ENDPROC
  8404.  
  8405.  
  8406. ENDDEFINE    && fp25ole
  8407.  
  8408. ************************************
  8409. DEFINE CLASS fp25form AS fp25obj
  8410. ************************************
  8411.     *- Subclass for handling the form
  8412.  
  8413.     cWinName = ""
  8414.  
  8415.     *----------------------
  8416.     PROCEDURE Init        && fp25form
  8417.     *----------------------
  8418.         PARAMETER parm1,parm2
  8419.         fp25obj::Init(parm1,parm2)
  8420.         THIS.iColorSource = I_WINCPCOLORSOURCE        && use "5" (Windows CP) for colorsource for forms
  8421.     ENDPROC
  8422.     
  8423.     *----------------------
  8424.     PROCEDURE AddBasic        && fp25form
  8425.     *----------------------
  8426.         fp25obj::AddBasic
  8427.         THIS.fp3id = SYS(2015)        && we'll sort on this field later
  8428.     ENDPROC
  8429.  
  8430.     *----------------------------------
  8431.     PROCEDURE AddMain        && fp25form
  8432.     *----------------------------------
  8433.     
  8434.         PRIVATE m.tmpstr,m.tmpcnt
  8435.         LOCAL m.ctmpname, lZoom
  8436.  
  8437.         *- Now add form record
  8438.         *- get form name
  8439.         IF EMPTY(THIS.formRef.cWnameExpr)
  8440.             IF EMPTY(a_scx2fld[A_NAME])
  8441.                 THIS.cWinName = THIS.GetNewName(THIS.fp3class)
  8442.             ELSE                
  8443.                 IF LEFT(a_scx2fld[A_NAME],1) = "("
  8444.                     *- indirect ref to window name
  8445.                     *- cFormName has been created above, before formset
  8446.                     *- is created (at same time environment/DNO is handled)
  8447.                     THIS.cWinName = THIS.formRef.cFormName
  8448.                 ELSE
  8449.                     *- check to see if form name is already used
  8450.                     IF TRIM(a_scx2fld[A_NAME]) $ THIS.formRef.cWinNames
  8451.                         *- duplicate name, so use made up one
  8452.                         THIS.cWinName = THIS.GetNewName(THIS.fp3class)
  8453.                     ELSE
  8454.                         THIS.cWinName = TRIM(a_scx2fld[A_NAME])
  8455.                         THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8456.                     ENDIF
  8457.                 ENDIF
  8458.             ENDIF
  8459.         ELSE
  8460.             IF EMPTY(a_scx2fld[A_NAME])
  8461.                 *- no name provided, so go ahead and use #WNAME directive value
  8462.                 THIS.cWinName = THIS.formRef.cWnameExpr
  8463.                 THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8464.             ELSE
  8465.                 *- check to see if form name is already used
  8466.                 IF TRIM(a_scx2fld[A_NAME]) $ THIS.formRef.cWinNames
  8467.                     *- duplicate name, so use #WNAME one
  8468.                     THIS.cWinName = THIS.formRef.cWnameExpr
  8469.                     THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8470.                 ELSE
  8471.                     IF THIS.formRef.cWnameExpr == "WZ_WIN"
  8472.                         *- assume this is a Wizard generated form, so use the #WNAME value (jd 7/15/96)
  8473.                         THIS.cWinName = THIS.formRef.cWnameExpr
  8474.                     ELSE
  8475.                         *- name and #WNAME directive value provided, and not Wizard -- use name
  8476.                         THIS.cWinName = TRIM(a_scx2fld[A_NAME])
  8477.                     ENDIF
  8478.                     THIS.formRef.cWinNames = THIS.formRef.cWinNames + "|" + THIS.cWinName    && add
  8479.                 ENDIF
  8480.             ENDIF
  8481.         ENDIF
  8482.         
  8483.         THIS.AddName(THIS.cWinName)
  8484.  
  8485.         *- adds form specific,window type properties
  8486.         *- window title (check for #itse)
  8487.         DO CASE
  8488.             CASE !EMPTY(THIS.formRef.itse_expr) AND SUBSTR(a_scx2fld[A_TAG],2,1) = THIS.formRef.itse_expr
  8489.                 THIS.AddProp(M_CAPTION,SUBSTR(a_scx2fld[A_TAG],3, RAT('"',a_scx2fld[A_TAG])-3))
  8490.             CASE !EMPTY(a_scx2fld[A_TAG])
  8491.                 THIS.AddProp(M_CAPTION,a_scx2fld[A_TAG])
  8492.             OTHERWISE
  8493.                 *- no title
  8494.                 THIS.AddProp(M_CAPTION,[""])
  8495.         ENDCASE
  8496.         
  8497.         IF !EMPTY(a_scx2fld[A_PICTURE])
  8498.             THIS.AddProp(M_FPICTURE,THIS.FullBMP(StripQuote(a_scx2fld[A_PICTURE]))) && wallpaper
  8499.         ENDIF
  8500.         IF !EMPTY(a_scx2fld[A_ORDER])
  8501.             THIS.AddProp(M_ICON,EVAL(a_scx2fld[A_ORDER])) &&icon
  8502.         ENDIF
  8503.         
  8504.         THIS.AddProp(M_BORDER,THIS.GetWBorder(a_scx2fld[A_BORDER]))
  8505.  
  8506.         IF INLIST(a_scx2fld[A_PLATFORM],C_DOS,C_UNIX)
  8507.             *- Add DOS footer (check for ITSE)
  8508.             DO CASE
  8509.                 CASE !EMPTY(THIS.formRef.itse_expr) AND SUBSTR(a_scx2fld[A_TAG2],2,1) = THIS.formRef.itse_expr
  8510.                     THIS.AddProp(M_TAGD,SUBSTR(a_scx2fld[A_TAG2],3, RAT('"',a_scx2fld[A_TAG2])-3))
  8511.                 CASE !EMPTY(a_scx2fld[A_TAG2])
  8512.                       THIS.AddProp(M_TAGD,a_scx2fld[A_TAG2])     
  8513.             ENDCASE
  8514.             *- Add shadow
  8515.             THIS.AddProp(M_SHADOW,a_scx2fld[A_SHADOW])
  8516.         ENDIF
  8517.                         
  8518.         *- Now check #WCLAUSE directive
  8519.         *- IN DESKTOP / IN SCREEN / IN WINDOW
  8520.         DO CASE
  8521.             CASE ATC("IN DESKTOP",THIS.formRef.wclause_expr) # 0
  8522.                 THIS.AddProp(M_DESKTOP,C_TRUE)
  8523.             CASE ATC("IN WINDOW",THIS.formRef.wclause_expr) # 0
  8524.                 m.tmpcnt = 1
  8525.                 DO WHILE UPPER(WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt))#"WINDOW"
  8526.                     m.tmpcnt = m.tmpcnt+1
  8527.                 ENDDO
  8528.                 m.tmpstr = WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt+1)
  8529.                 THIS.AddProp(M_WINDOW,m.tmpstr)
  8530.             CASE ATC("IN SCREEN",THIS.formRef.wclause_expr) # 0
  8531.                 THIS.AddProp(M_WINDOW,C_TRUE)
  8532.         ENDCASE
  8533.         
  8534.         *- GROW
  8535.         THIS.AddProp(M_GROW,ATC(" GROW",THIS.formRef.wclause_expr) # 0)
  8536.         
  8537.         *- ZOOM - Maximize
  8538.         m.lZoom = ATC(" ZOOM",THIS.formRef.wclause_expr) # 0
  8539.                 
  8540.         *- MDI
  8541.         THIS.AddProp(M_MDI,ATC(" MDI",THIS.formRef.wclause_expr) # 0)
  8542.  
  8543.         THIS.AddProp(M_MAXIMIZE,m.lZoom)
  8544.         THIS.AddProp(M_ZOOMBOX,m.lZoom)                    && for the Mac (jd 02.14.95)
  8545.         THIS.AddProp(M_FLOAT,a_scx2fld[A_FLOAT])
  8546.         THIS.AddProp(M_CLOSE,a_scx2fld[A_CLOSE])
  8547.         THIS.AddProp(M_MINIMIZE,a_scx2fld[A_MINIMIZE])
  8548.         IF (!a_scx2fld[A_FLOAT] AND !a_scx2fld[A_CLOSE] AND !a_scx2fld[A_MINIMIZE] AND !m.lZoom)
  8549.             THIS.AddProp(M_CONTROLBOX,.F.)
  8550.         ENDIF
  8551.             
  8552.         THIS.AddProp(M_HALF,a_scx2fld[A_TAB])
  8553.  
  8554.  
  8555.         *- Color Scheme
  8556.         IF ATC("COLORSCHEME",THIS.formRef.wclause_expr) # 0
  8557.             m.tmpcnt = 1
  8558.             DO WHILE UPPER(WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt))#"COLORSCHEME"
  8559.                 m.tmpcnt = m.tmpcnt+1
  8560.             ENDDO
  8561.             m.tmpstr = WORDNUM(THIS.formRef.wclause_expr,m.tmpcnt+1)
  8562.             THIS.AddProp(M_SCHEME,m.tmpstr)
  8563.         ENDIF
  8564.             
  8565.         *- support indirect reference to file names
  8566.         IF THIS.FormRef.lIndirectWinName
  8567.             THIS.AddMethods(M_INIT,;
  8568.                 C_CRLF + ;
  8569.                 "THIS.Name = " + ;
  8570.                 THIS.FormRef.cIndirectWinName + ;
  8571.                 C_CRLF,1)
  8572.         ENDIF
  8573.  
  8574.         *- section 2 code goes into FORM.LOAD method
  8575.         IF !EMPTY(THIS.formRef.a_reads[2])
  8576.             THIS.AddMethods(M_SETUP2,THIS.formRef.a_reads[2],1)
  8577.             *- clear out setup var, so it isn;t added to more than one screen in set
  8578.             THIS.formRef.a_reads[2] = ""
  8579.         ENDIF
  8580.         IF !EMPTY(THIS.formRef.cMainCurs)
  8581.             THIS.AddMethods(M_FORMACTIVATE,"SELECT " + THIS.formRef.cMainCurs + C_CRLF,1)
  8582.         ENDIF
  8583.  
  8584.     ENDPROC
  8585.     
  8586.     *----------------------------------
  8587.     PROCEDURE Premap        && fp25form
  8588.     *----------------------------------
  8589.         *- We need to reset for screen sets
  8590.         THIS.formRef.parentName = THIS.formRef.cFormSetName
  8591.     ENDPROC
  8592.         
  8593.     *----------------------------------
  8594.     PROCEDURE Postmap        && fp25form
  8595.     *----------------------------------
  8596.  
  8597.         THIS.formRef.parentName = THIS.formRef.parentName + "." + THIS.fp3name
  8598.  
  8599.         *- get form fontmetrics for other records
  8600.         IF INLIST(a_scx2fld[A_PLATFORM],C_MAC,C_WINDOWS)
  8601.             THIS.formRef.nDeffont1 = THIS.fp3font1     && default screen font1
  8602.             THIS.formRef.nDeffont5 = THIS.fp3font5     && default screen font5
  8603.             THIS.formRef.nDeffont6 = THIS.fp3font6     && default screen font6
  8604.         ENDIF
  8605.         
  8606.         *- Need to get default screen color for transparent objects
  8607.         IF a_scx2fld[A_FILLRED] = -1
  8608.             THIS.formRef.cDefcolor = "255,255,255"
  8609.         ELSE
  8610.             THIS.formRef.cDefcolor = ALLT(STR(a_scx2fld[A_FILLRED]))+;
  8611.                 ","+ALLT(STR(a_scx2fld[A_FILLGREEN]))+;
  8612.                 ","+ALLT(STR(a_scx2fld[A_FILLBLUE]))
  8613.         ENDIF
  8614.         
  8615.         *- Add form record here so that
  8616.         *- PageFrame rec gets added automatically
  8617.         THIS.AddProp(M_NAME,THIS.fp3name)
  8618.         
  8619.         *- Add Form / PageFrame / FormPage record
  8620.         IF !THIS.FormRef.lDevMode
  8621.             THIS.AddRec
  8622.             THIS.AddPage()
  8623.         ENDIF
  8624.  
  8625.     ENDPROC
  8626.  
  8627.     *----------------------------------
  8628.     PROCEDURE WriteName
  8629.     *----------------------------------
  8630.     ENDPROC
  8631.     
  8632.     *----------------------------------
  8633.     PROCEDURE AddPage
  8634.     *----------------------------------
  8635.         *- Note: we add an invisible form page here
  8636.         *- to simulate the first READ level.
  8637.         THIS.fp3class = T_PAGE            && class
  8638.         THIS.fp3base = T_PAGE            && baseclass
  8639.         THIS.fp3prop = ""                && properties
  8640.         THIS.fp3method = ""                && methods
  8641.         THIS.AddBasic
  8642.         THIS.fp3comment    = a_scx2fld[A_COMMENT]         && comment
  8643.         THIS.fp3parent = THIS.formRef.parentName
  8644.         THIS.fp3name = C_PAGEFRAME
  8645.         THIS.AddProp(M_VPOS,0)
  8646.         THIS.AddProp(M_HPOS,0)
  8647.         THIS.AddProp(M_HEIGHT,30000)
  8648.         THIS.AddProp(M_WIDTH,30000)
  8649.         THIS.AddProp(M_FORMPAGES,1)
  8650.         THIS.AddProp(M_PENSIZE,0)    &&borderwidth
  8651.         THIS.AddProp(M_FORMTABS,C_FALSE)
  8652.         THIS.AddProp(M_ERASEPAGE,C_FALSE)
  8653.         THIS.AddProp(M_DRAWFRAME,C_FALSE)
  8654.         THIS.AddProp(M_NAME,C_PAGEFRAME)
  8655.         THIS.AddProp(C_DEFPAGE+"."+M_MODE,0)
  8656.         THIS.AddProp(C_DEFPAGE+"."+M_NAME,THIS.AddQuotes(C_DEFPAGE))
  8657.         
  8658.         THIS.formRef.parentName = THIS.formRef.parentName + ;
  8659.             "." + C_PAGEFRAME + "." + C_DEFPAGE
  8660.     ENDPROC
  8661.  
  8662.     *----------------------------------
  8663.     PROCEDURE AddPos        && fp25form
  8664.     *----------------------------------
  8665.         *- Add object positions in pixels (how Taz stores it)
  8666.         
  8667.         PRIVATE m.arrange,m.larrflag,m.lcentflag,m.nrow,m.ncol
  8668.         STORE "" TO m.arrange
  8669.         STORE .F. TO m.larrflag,m.lcentflag
  8670.         STORE 0 TO m.nrow,m.ncol
  8671.  
  8672.         THIS.nDeffont1 = THIS.fp3font1
  8673.         THIS.nDeffont5 = THIS.fp3font5
  8674.         THIS.nDeffont6 = THIS.fp3font6
  8675.  
  8676.         *- WIDTH based on object font
  8677.         THIS.AddProp(M_WIDTH,a_scx2fld[A_WIDTH] * THIS.fp3font6)
  8678.  
  8679.         *- HEIGHT based on object font
  8680.         *- Add title bar height for 3.0 style forms
  8681.         THIS.AddProp(M_HEIGHT,a_scx2fld[A_HEIGHT]*;
  8682.           (THIS.fp3font1+THIS.fp3font5))
  8683.           
  8684.         *- check if we have arranged screen from project
  8685.         *- VPOS,HPOS based on form font
  8686.  
  8687.         m.arrange = THIS.formRef.a_scx2files[THIS.formRef.formnum,2]
  8688.         
  8689.         IF !EMPTY(m.arrange)
  8690.             =getarrange(m.arrange,ALLTRIM(a_scx2fld[A_PLATFORM]),@larrflag,@lcentflag,@nrow,@ncol,a_scx2fld[A_CENTER])
  8691.             IF m.larrflag AND !m.lcentflag
  8692.                 *- FoxPro 2.x used the current screen settings to calculate the row and col in foxels
  8693.                 THIS.AddProp(M_VPOS,m.nrow*FONT(1,WFONT(1,"screen"),WFONT(2,"screen"),WFONT(3,"screen"))) && (THIS.nDeffont1+THIS.nDeffont5)    
  8694.                 THIS.AddProp(M_HPOS,m.ncol*FONT(6,WFONT(1,"screen"),WFONT(2,"screen"),WFONT(3,"screen"))) &&    THIS.nDeffont6
  8695.             ENDIF
  8696.         ELSE
  8697.             *- most likely a screen by itself
  8698.             m.lcentflag = a_scx2fld[A_CENTER]
  8699.         ENDIF
  8700.         
  8701.         IF !m.larrflag 
  8702.           THIS.AddProp(M_VPOS,a_scx2fld[A_VPOS]*(THIS.nDeffont1+THIS.nDeffont5))        
  8703.           THIS.AddProp(M_HPOS,a_scx2fld[A_HPOS]*THIS.nDeffont6)
  8704.         ENDIF
  8705.         
  8706.         *- add Autocenter property
  8707.         THIS.AddProp(M_CENTER,m.lcentflag)
  8708.         
  8709.     ENDPROC    && AddPos
  8710.  
  8711.     *----------------------
  8712.     PROCEDURE AddRec        && fp25form
  8713.     *----------------------
  8714.         *- Add record to FORM file    
  8715.         *- Override base class method, since form record needs
  8716.         *- special key word in reserved4 field
  8717.         IF THIS.formRef.lDevMode
  8718.             *- put methods someplace else
  8719.             INSERT INTO (THIS.formRef.new30alias) ;
  8720.                 (platform,uniqueid,timestamp,;
  8721.                 class,baseclass,objname,parent,properties,;
  8722.                 user,reserved1,reserved4,reserved6);
  8723.             VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  8724.                 THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  8725.                 THIS.fp3parent,THIS.fp3prop,;
  8726.                 THIS.fp3comment,;
  8727.                 THIS.fp3reserved1,;
  8728.                 IIF(!THIS.formref.a_pjxsets[A_DEFWINDOWS] AND ;
  8729.                     THIS.fp3class = T_FORM,"NODEFINE",""),;
  8730.                     THIS.fp3reserved6)
  8731.             IF !EMPTY(THIS.fp3method)
  8732.                 REPLACE _fox3spr.code WITH C_SEPARATOR + THIS.fp3name + C_CRLF + THIS.fp3method ADDITIVE
  8733.             ENDIF
  8734.         ELSE
  8735.             *- put methods someplace else
  8736.             INSERT INTO (THIS.formRef.new30alias) ;
  8737.                 (platform,uniqueid,timestamp,;
  8738.                 class,baseclass,objname,parent,properties,;
  8739.                 methods,user,reserved1,reserved4,reserved6);
  8740.             VALUES(THIS.fp3saveplat,THIS.fp3id,THIS.fp3time,;
  8741.                 THIS.fp3class,THIS.fp3base,THIS.fp3name,;
  8742.                 THIS.fp3parent,THIS.fp3prop,;
  8743.                 THIS.fp3method,;
  8744.                 THIS.fp3comment,;
  8745.                 THIS.fp3reserved1,;
  8746.                 IIF(!THIS.formref.a_pjxsets[A_DEFWINDOWS] AND ;
  8747.                     THIS.fp3class = T_FORM,"NODEFINE",""),;
  8748.                     THIS.fp3reserved6)
  8749.         ENDIF
  8750.     ENDPROC
  8751.  
  8752.     *----------------------------------
  8753.     FUNCTION GetWBorder
  8754.     *----------------------------------
  8755.         *- Note: FPW 2.x did not properly handle
  8756.         *- single and double border windows as in 3.0 
  8757.         
  8758.         PARAMETER wstyle
  8759.         DO CASE
  8760.             CASE m.wstyle = 0    && no border ???
  8761.                 RETURN 0
  8762.             CASE m.wstyle = 1    && single border
  8763.                 RETURN 1
  8764.             CASE m.wstyle = 2    && double border
  8765.                 RETURN 2
  8766.             CASE m.wstyle = 3    && panel border
  8767.                 RETURN 2
  8768.             CASE m.wstyle = 4    && system border
  8769.                 RETURN 2
  8770.         ENDCASE
  8771.     ENDFUNC
  8772.  
  8773.     
  8774.     *----------------------
  8775.     FUNCTION GetNewName    && fp25form
  8776.     *----------------------
  8777.         *- override fp25obj -- generate a unique form name
  8778.         PARAMETER newobj
  8779.  
  8780.         RETURN SYS(2015)
  8781.  
  8782.     ENDFUNC        && GetNewName
  8783.     
  8784.  
  8785. ENDDEFINE
  8786.  
  8787. ************************************
  8788. DEFINE CLASS fpdatanav AS fp25obj
  8789. ************************************
  8790.     
  8791.     cOldParentName = ""
  8792.     fp3objtype = 0
  8793.  
  8794.     *----------------------------------
  8795.     PROCEDURE Init            && fpdatanav
  8796.     *----------------------------------
  8797.         PARAMETER parm1,parm2
  8798.         
  8799.         fp25obj::Init(parm1,parm2)
  8800.         
  8801.         THIS.cOldParentName = THIS.formRef.parentName
  8802.         
  8803.         IF !THIS.formRef.lHasDataNavObj
  8804.             *- add a data nav object for this screen, and
  8805.             *- set flag so we don't come back here again
  8806.             THIS.formRef.parentName = ""
  8807.             THIS.fp3comment    = ""        && comment
  8808.             THIS.fp3objtype = N_FRX_DATAENV
  8809.             THIS.mapit
  8810.             THIS.addrec
  8811.             THIS.formRef.nDNORecNo = RECNO(THIS.formRef.new30alias)
  8812.             THIS.formRef.lHasDataNavObj = .T.
  8813.             THIS.ClearProp                && clear properties before continuing
  8814.         ENDIF
  8815.         *- set class values to "cursor"
  8816.         THIS.formRef.parentName = C_DEFDATANAV
  8817.         THIS.fp3class  = T_CURSOR            && class
  8818.         THIS.fp3base   = T_CURSOR            && baseclass
  8819.         RETURN
  8820.     ENDPROC
  8821.  
  8822.     *----------------------
  8823.     PROCEDURE AddBasic        && fpdatanav
  8824.     *----------------------
  8825.         fp25obj::AddBasic
  8826.         THIS.fp3id         = '^'                         && we'll sort on this field later -- goes after alpha, and before "_"
  8827.     ENDPROC
  8828.  
  8829.     *----------------------------------
  8830.     PROCEDURE MapIt
  8831.     *----------------------------------
  8832.     *- overwrite the MapIt procedure
  8833.         THIS.PreMap
  8834.         THIS.AddBasic
  8835.         THIS.AddMain
  8836.         THIS.PostMap
  8837.         THIS.WriteName     && note Name property must be written last!
  8838.         THIS.formRef.nDNOCount = THIS.formRef.nDNOCount + 1 
  8839.     ENDPROC
  8840.     
  8841.     *----------------------------------
  8842.     PROCEDURE AddMain        && fpdatanav
  8843.     *----------------------------------
  8844.  
  8845.         LOCAL nlen, cSaveArea, nCurrec
  8846.  
  8847.         *- Now add DE specific properties
  8848.         IF !THIS.formRef.lHasDataNavObj
  8849.             THIS.AddName(THIS.fp3class)
  8850.         ELSE
  8851.             THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8852.         ENDIF
  8853.         
  8854.         IF !THIS.formRef.lHasDataNavObj
  8855.             *- this is the data navigation container
  8856.             THIS.AddProp(M_AUTOLOADENV,THIS.formRef.lAutoOpen)
  8857.             THIS.AddProp(M_AUTOUNLOADENV,THIS.formRef.lAutoClose)
  8858.             STORE SELECT() TO m.savearea
  8859.             SELECT (THIS.formRef.c25alias)
  8860.             m.nCurrec = RECNO()
  8861.             LOCATE FOR objtype = 2 AND platform = THIS.formRef.platform
  8862.             SCAN WHILE objtype = 2 AND platform = THIS.formRef.platform
  8863.                 THIS.formRef.cMainCurs = IIF(EMPTY(THIS.formRef.cMainCurs) AND unique,ALLT(tag),THIS.formRef.cMainCurs)
  8864.             ENDSCAN
  8865.             IF m.nCurrec > RECC()
  8866.                 GO BOTTOM
  8867.                 SKIP
  8868.             ELSE
  8869.                 GO m.nCurrec
  8870.             ENDIF
  8871.             SELECT (m.savearea)
  8872.             THIS.AddProp(M_INITIALALIAS,THIS.formRef.cMainCurs)
  8873.         ELSE
  8874.             *- alias
  8875.             THIS.AddProp(M_ALIAS,a_scx2fld[A_TAG])
  8876.             
  8877.             *- cursor source
  8878.             THIS.AddProp(M_CURSORSRC,THIS.FullBMP(a_scx2fld[A_NAME]))
  8879.             
  8880.             *- order
  8881.             IF !EMPTY(ALLT(a_scx2fld[A_TAG2]))
  8882.                 THIS.AddProp(M_ORDER,a_scx2fld[A_TAG2])
  8883.             ENDIF
  8884.  
  8885.             *- remember index orders
  8886.             m.nlen = ALEN(THIS.formRef.a_tables)
  8887.             IF !(m.nlen = 1 AND EMPTY(THIS.formRef.a_tables[1]))
  8888.                 *- grow array
  8889.                 m.nlen = m.nlen + 1
  8890.                 DIMENSION THIS.formRef.a_tables[m.nlen]
  8891.                 DIMENSION THIS.formRef.a_torder[m.nlen]
  8892.             ENDIF
  8893.             THIS.formRef.a_tables[m.nlen] = ALLTRIM(a_scx2fld[A_TAG])
  8894.             THIS.formRef.a_torder[m.nlen] = ALLTRIM(a_scx2fld[A_TAG2])
  8895.  
  8896.             *- filter?
  8897.         
  8898.         ENDIF
  8899.                 
  8900.     ENDPROC        &&  fpdatanav:AddMain
  8901.  
  8902.     *----------------------------------
  8903.     FUNCTION GetNewName    && fp25datanav
  8904.     *----------------------------------
  8905.         PARAMETER newobj
  8906.         THIS.formRef.nObjCount = THIS.formRef.nObjCount + 1
  8907.         RETURN ALLTRIM(m.newobj) + ALLTRIM(STR(THIS.formRef.nObjCount))
  8908.     ENDFUNC && fp25datanav:GetNewName
  8909.  
  8910.     *----------------------------------
  8911.     PROCEDURE Destroy
  8912.     *----------------------------------
  8913.         *- reset remembered parentName
  8914.         THIS.formRef.parentName = THIS.cOldParentName
  8915.     ENDPROC
  8916. ENDDEFINE
  8917.  
  8918. ************************************
  8919. DEFINE CLASS fpFRXdatanav AS fpdatanav
  8920. ************************************
  8921.  
  8922.     *------------------
  8923.     PROCEDURE AddRec            && fpFRXdatanav
  8924.     *------------------
  8925.         THIS.fp3plat = THIS.GetPlatform()         && platform: NOTE -- forces to be current platform
  8926.  
  8927.         *- add a record to the 3.0 FRX file
  8928.         *- environ == private data session, always set it to .F.
  8929.         INSERT INTO (THIS.formRef.new30alias) ;
  8930.                 (platform,uniqueid,timestamp,objtype,name,expr,environ);
  8931.             VALUES(THIS.fp3plat,THIS.fp3id,THIS.fp3time,;
  8932.                 THIS.fp3objtype,THIS.fp3class,THIS.fp3prop,.F.)
  8933.  
  8934.     ENDPROC
  8935.  
  8936. ENDDEFINE
  8937.  
  8938. ************************************
  8939. DEFINE CLASS fpDataNavRelation AS fpdatanav
  8940. ************************************
  8941.  
  8942.     cAlias = ""
  8943.  
  8944.     *----------------------------------
  8945.     PROCEDURE Init
  8946.     *----------------------------------
  8947.         PARAMETER parm1,parm2
  8948.         
  8949.         fp25obj::Init(parm1,parm2)
  8950.             
  8951.         THIS.cOldParentName = THIS.formRef.parentName
  8952.         THIS.formRef.parentName = C_DEFDATANAV
  8953.     
  8954.     ENDPROC        &&  fpDataNavRelation::Init
  8955.     
  8956.     *----------------------------------
  8957.     PROCEDURE AddMain        && fpDataNavRelation
  8958.     *----------------------------------
  8959.  
  8960.         LOCAL npos, loldexact, nrec, m.savearea, nworkarea
  8961.  
  8962.         *- Now add relation properties
  8963.         IF !THIS.formRef.lHasDataNavObj
  8964.             THIS.AddName(THIS.fp3class)
  8965.         ELSE
  8966.             THIS.AddName(THIS.GetNewName(THIS.fp3class))
  8967.         ENDIF
  8968.         
  8969.         *- parent alias
  8970.         THIS.AddProp(M_PARENTALIAS,a_scx2fld[A_TAG2])
  8971.         
  8972.         *- parent index expr
  8973.         THIS.AddProp(M_PARENTINDEXEXPR,a_scx2fld[A_EXPR])
  8974.         
  8975.         *- child alias
  8976.         THIS.AddProp(M_CHILDALIAS,a_scx2fld[A_TAG])
  8977.         
  8978.         *- child index expr
  8979.         m.loldexact = SET("EXACT")
  8980.         npos = ASCAN(THIS.formRef.a_tables,TRIM(a_scx2fld[A_TAG]))
  8981.         IF m.npos > 0
  8982.             THIS.AddProp(M_CHILDINDEXTAG,THIS.formRef.a_torder[m.npos])
  8983.         ENDIF
  8984.         SET EXACT &loldexact
  8985.  
  8986.         *- always set one-to-many
  8987.         *- remember this record
  8988.         m.savearea = SELECT()
  8989.         nWorkArea = a_scx2fld[A_OBJCODE]
  8990.         SELECT (THIS.formRef.c25alias)
  8991.         m.nrec = RECNO()
  8992.         LOCATE FOR objtype = 2 AND objcode = m.nWorkArea AND platform = THIS.formRef.platform AND !EMPTY(expr) AND !environ
  8993.         IF FOUND()
  8994.             *- THIS.AddProp(M_ONETOMANY,.T.)
  8995.             *- do it the hard way
  8996.             THIS.FormRef.cSetSkip = THIS.FormRef.cSetSkip + C_SELECT + LOWER(ALLT(tag)) + C_CR + ;
  8997.                 C_SETSKIP + LOWER(ALLT(expr)) + C_CR
  8998.             *- mark the record so we don;t hit it again -- this file is temporary, so we can touch it
  8999.             REPLACE environ WITH .T.
  9000.         ENDIF
  9001.         GOTO IIF(m.nrec > RECC(),RECC(),m.nrec)
  9002.         SELECT (m.savearea)
  9003.  
  9004.     ENDPROC        &&  fpDataNavRelation:AddMain
  9005.  
  9006. ENDDEFINE && fpDataNavRelation
  9007.  
  9008. ************************************
  9009. DEFINE CLASS fpFRXDataNavRelation AS fpDataNavRelation
  9010. ************************************
  9011.  
  9012.     *------------------
  9013.     PROCEDURE AddRec            && fpFRXDataNavRelation
  9014.     *------------------
  9015.         THIS.fp3plat = THIS.GetPlatform()         && platform: NOTE -- forces to be current platform
  9016.  
  9017.         *- add a record to the 3.0 FRX file
  9018.         *- environ == private data session, always set it to .F.
  9019.         INSERT INTO (THIS.formRef.new30alias) ;
  9020.                 (platform,uniqueid,timestamp,objtype,name,expr,environ);
  9021.             VALUES(THIS.fp3plat,THIS.fp3id,THIS.fp3time,;
  9022.                 THIS.fp3objtype,THIS.fp3class,THIS.fp3prop,.F.)
  9023.  
  9024.     ENDPROC
  9025.  
  9026. ENDDEFINE
  9027.  
  9028. *-
  9029. *- eof CONVERT.PRG
  9030. *-
  9031.